SAS Stored Processes
Using Sessions: A Sample Web ApplicationThe following sample Web application demonstrates some of the features of stored process sessions. The sample application is an online library. Users can log on, select one or more items to check out of the library, and request by e-mail that the selected items be delivered. The sample code shows how to create a session and then create, modify, and view macro variables and data sets in that session. See the section about Sessions for more information. Sample DataThis sample requires a LIB_INVENTORY data set in the SAMPDAT library that is used for other SAS Integration Technology samples. You can create the data set in Windows using the following code. You can also use the code in other operating environments by making the appropriate modifications to the SAMPDAT LIBNAME statement. libname SAMPDAT 'C:\My Demos\Library'; data SAMPDAT.LIB_INVENTORY; length type $10 desc $80; input refno 1-5 type 7-16 desc 17-80; datalines4; 17834 BOOK SAS/GRAPH Software: Reference 32345 BOOK SAS/GRAPH Software: User's Guide 52323 BOOK SAS Procedures Guide 54337 BOOK SAS Host Companion for UNIX Environments 35424 BOOK SAS Host Companion for OS/390 Environment 93313 AUDIO The Zen of SAS 34222 VIDEO Getting Started with SAS 34223 VIDEO Introduction to AppDev Studio 34224 VIDEO Building Web Applications with SAS Stored Processes 70001 HARDWARE Cellphone - Model 5153 70002 HARDWARE Video Projector - Model 79F15 ;;;; Main Aisle Stored ProcessThe main aisle page is generated by the Main Aisle stored process. This page acts as a welcome page if new users. A session is created the first time a user executes this stored process. /* Main Aisle of the Online Library */ data _null_; file _webout; if libref('SAVE') ne 0 then rc = stpsrv_session('create'); put '<HTML>'; put '<HEAD><TITLE>Online Library Main Aisle</TITLE></HEAD>'; put; put '<BODY vlink="#004488" link="#0066AA" bgcolor="#E0E0E0">'; put '<H1>Online Library Main Aisle</H1>'; put; put 'Select one of the following areas of the library:'; put '<UL>'; length hrefroot $400; hrefroot = symget('_THISSESSION') || '&_PROGRAM=/WebApps/Library/'; put '<LI><A HREF="' hrefroot +(-1) 'Aisles&type=Book">Book Aisle</A></LI>'; put '<LI><A HREF="' hrefroot +(-1) 'Aisles&type=Video">Video Aisle</A></LI>'; put '<LI><A HREF="' hrefroot +(-1) 'Aisles&type=Audio">Audio Aisle</A></LI>'; put '<LI><A HREF="' hrefroot +(-1) 'Aisles&type=Hardware">Hardware Aisle</A></LI>'; put '<LI><A HREF="' hrefroot +(-1) 'Shopping Cart">View my shopping cart</A></LI>'; put '<LI><A HREF="' hrefroot +(-1) 'Logout">Logout</A></LI>'; put '</UL>'; put '</BODY>'; put '</HTML>'; run; The main aisle page consists of a list of links to specific sections of the Online Library. Each link in this page is built using the _THISSESSION macro variable. This variable includes both the _URL value pointing back to the Stored Process Web Application and the _SESSIONID value identifying the session. Aisles Stored ProcessThe library is divided into aisles for different categories of library items. The pages for each aisle are generated by one shared Aisles stored process. The stored process accepts a TYPE input variable that determines which items to display. /* Aisles - List items in a specified aisle. The aisle is specified by the TYPE variable. */ libname SAMPDAT 'C:\My Demos\Library'; /* Build a temporary data set that contains the selected type, and add links for selecting and adding items to the shopping cart. */ data templist; if libref('SAVE') ne 0 then rc = stpsrv_session('create'); set SAMPDAT.LIB_INVENTORY; where type="%UPCASE(&type)"; length select $200; select = '<A HREF="' || symget("_THISSESSION") || '&_program=/WebApps/Library/Add+Item&REFNO=' || trim(left(refno)) || '&TYPE=' || "&TYPE" || '">Add to cart</A>'; run; ods html body=_webout(nobot) rs=none; title Welcome to the &type Aisle; proc print data=templist noobs label; var refno desc select; label refno='RefNo' desc='Description' select='Select'; run; ods html close; data _null_; file _webout; put '<P>'; put 'Return to <A HREF="' "&_THISSESSION" '&_PROGRAM=/WebApps/Library/Main+Aisle' '">main aisle</A><BR>'; put 'View my <A HREF="' "&_THISSESSION" '&_PROGRAM=/WebApps/Library/Shopping+Cart' '">shopping cart</A><BR>'; put '</BODY>'; put '</HTML>'; run; The stored process selects a subset of the LIB_INVENTORY data set using a WHERE clause, and then uses PROC PRINT to create an HTML table. A temporary data set is created that contains the selected items in order for an additional column to be generated that has an HTML link for users to add the item to their shopping cart. In this stored process, both ODS and a DATA step are used to generate HTML. The ODS HTML statement includes the NOBOT option that indicates that more HTML will be appended after the ODS HTML CLOSE statement. The navigation links are then added using a DATA step. Add Item Stored ProcessThe Add Item stored process is run when the user clicks the Add to cart link in the aisle item table. The specified item is copied from the LIB_INVENTORY data set to a shopping cart data set in the session library (SAVE.CART). The session and the data set will remain accessible to all programs in the same session until the session is deleted or it times out. /* Add Item - Add a selected item to the shopping cart. This stored process uses REFNO and TYPE input variables to identify the item. */ libname SAMPDAT 'C:\My Demos\Library'; /* Perform REFNO and TYPE verification here. */ /* Append the selected item. */ proc append base=SAVE.CART data=SAMPDAT.LIB_INVENTORY; where refno=&refno; run; /* Print the page. */ data _null_; file _webout; put '<HTML>'; put '<HEAD><TITLE>Selected Item Added to Shopping Cart</TITLE></HEAD>'; put '<BODY vlink="#004488" link="#0066AA" bgcolor="#E0E0E0">'; put "<H1>Item &refno Added</H1>"; put 'Return to <A HREF="' "&_THISSESSION" '&_PROGRAM=/WebApps/Library/Aisles' '&TYPE=' "&TYPE" '">' "&TYPE aisle</A><BR>"; put 'Return to <A HREF="' "&_THISSESSION" '&_PROGRAM=/WebApps/Library/Main+Aisle' '">main aisle</A><BR>'; put 'View my <A HREF="' "&_THISSESSION" '&_PROGRAM=/WebApps/Library/Shopping+Cart' '">shopping cart</A><BR>'; put '</BODY>'; put '</HTML>'; run; The program prints an information page that has navigation links. Shopping Cart Stored ProcessThe Shopping Cart stored process displays the contents of the shopping cart. /* Shopping Cart - Display contents of the shopping cart * (SAVE.CART data set). */ %macro lib_cart; %let CART=%sysfunc(exist(SAVE.CART)); %if &CART %then %do; /* This program could use the same technique as the LIB_AISLE program in order to add a link to each line of the table that removes items from the shopping cart. */ /* Print the CART contents. */ ods html body=_webout(nobot) rs=none; title Your Selected Items; proc print data=SAVE.CART noobs label; var refno desc; label refno='RefNo' desc='Description'; run; ods html close; %end; %else %do; /* No items in the cart. */ data _null_; file _webout; put '<HTML>'; put '<HEAD><TITLE>No items selected</TITLE></HEAD>'; put '<BODY vlink="#004488" link="#0066AA" bgcolor="#E0E0E0">'; put '<H1>No Items Selected</H1>'; put; run; %end; /* Print navigation links. */ data _null_; file _webout; put '<P>'; if &CART then do; put '<FORM ACTION="' "&_url" '">'; put '<INPUT TYPE="HIDDEN" NAME="_program" VALUE="/WebApps/Library/Logout">'; put '<INPUT TYPE="HIDDEN" NAME="_sessionid" VALUE="' "&_sessionid" '">'; put '<INPUT TYPE="HIDDEN" NAME="CHECKOUT" VALUE="YES">'; put '<INPUT TYPE="SUBMIT" VALUE="Request these items">'; put '</FORM><P>'; end; put 'Return to <A HREF="' "&_THISSESSION" '&_PROGRAM=/WebApps/Library/Main+Aisle' '">main aisle</A><BR>'; put '<A HREF="' "&_THISSESSION" '&_PROGRAM=/WebApps/Library/Logout' '&CHECKOUT=NO">Logout</A><BR>'; put '</BODY>'; put '</HTML>'; run; %mend; %lib_cart; The contents of the shopping cart are displayed using a PROC PRINT statement. The page also includes a request button and navigation links. The request button is part of an HTML form. In order to connect to the same session, include the _SESSIONID value in addition to the normal _PROGRAM value. These values are usually specified as hidden fields. This program also has a hidden CHECKOUT field that is initialized to YES in order to indicate that the user is requesting the items in the cart. Logout Stored ProcessThe Logout stored process checks the user out of the Online Library. If the CHECKOUT input variable is YES, then all of the items in the user's shopping cart are requested via e-mail. /* Logout - logout of Online Library application. Send e-mail to the library@abc.com account with requested item if CHECKOUT=YES is specified. */ %macro lib_logout; %global CHECKOUT; /* Define CHECKOUT in case it was not input. */ %if %UPCASE(&CHECKOUT) eq YES %then %do; /* Checkout - send an e-mail request to the library. See the documentation for the email access method on your platform for more information on the required options. */ /* ***************** disabled for demo ************* filename RQST EMAIL 'library@abc.com' SUBJECT='Online Library Request for &_USERNAME'; ods listing body=RQST; title Request for &_USERNAME; proc print data=SAVE.CART label; var refno type desc; label refno='RefNo' type='Type' desc='Description'; run; ods listing close; * *********************************************** */ data _null_; file _webout; put '<HTML>'; put '<HEAD><TITLE>Library Checkout</TITLE></HEAD>'; put '<BODY vlink="#004488" link="#0066AA" bgcolor="#E0E0E0">'; put '<H1>Library Checkout</H1>'; put; put 'The items in your shopping cart have been requested.'; put '<P>Requested items will normally arrive via interoffice'; put 'mail by the following day. Thank you for using the Online Library.'; put '<P><A HREF="' "&_URL" '?_PROGRAM=/WebApps/Library/Main+Aisle" >Click here</A>'; put 'to re-enter the application.'; put '</BODY>'; put '</HTML>'; run; %end; %else %do; /* Logout without requesting anything. */ data _null_; file _webout; put '<HTML>'; put '<HEAD><TITLE>Logout</TITLE></HEAD>'; put '<BODY vlink="#004488" link="#0066AA" bgcolor="#E0E0E0">'; put '<H1>Library Logout</H1>'; put; put '<P>Thank you for using the Online Library.'; put '<P><A HREF="' "&_URL" '?_PROGRAM=/WebApps/Library/Main+Aisle" >Click here</A>'; put 'to re-enter the application.'; put '</BODY>'; put '</HTML>'; run; %end; %mend; %lib_logout; /* User is finished - delete the session. */ %let rc=%sysfunc(stpsrv_session(delete)); An information page is displayed if the user chooses to request the shopping cart items. A simple logout screen is displayed if the user selects the Logout link. Note: Logging out is not required. All sessions have an associated timeout (the default is 15 minutes). If the session is not accessed for the duration of the timeout, the session and all temporary data in the session will be deleted. In this sample, the SAVE.CART data set would be automatically deleted when the session timeout is reached. You can change the session timeout using the STPSRVSET('session timeout',seconds) function inside the program. |