SAS Stored Processes
Chaining Stored ProcessesOnly the simplest stored process Web applications contain a single Web page. With the addition of a second and subsequent pages, you face the problem of passing information from one page to another. It is also typical to have an application that contains more than a single stored process. This means that you must find a way to connect the stored processes that compose your application and make sure that all of the data collected along the way is available in the appropriate places. It is good programming practice to design applications so that they do not request the same information multiple times. Because HTTP is a stateless environment, each request is separate from all other requests. If a user enters a phone number on the first page of an application and submits the form, that phone number is available as an input parameter to the first stored process. After that stored process completes, the input parameters are lost unless they are explicitly saved. If the second or third stored process in the application needs to know the specified phone number, the application must ask for the phone number again. There are several ways to solve this problem. You can store data values in the following locations:
Passing Data Through Form Fields or URL ParametersStoring data on the client in hidden fields or URL parameters is the simplest technique. To do this, you must dynamically generate all of the HTML pages in your application except for the initial page. Because each page functions as a mechanism for transporting data values from the previous stored process to the next stored process, it cannot be static HTML stored in a file. Usually, the application takes the following steps:
Each hidden field in the second form can contain one name/value data pair passed from the first form. You should use unique names for all of the data values in the entire application. In this way you can pass all of the application data throughout the entire application. When you dynamically generate the second form, you can write out the name of the second stored process in the hidden field _PROGRAM. Because the first stored process contains the logic to determine the second stored process, this is referred to as chaining stored processes. A stored process can chain to multiple stored processes depending on the link a user chooses or on data entered by the users. The stored process can even chain back to itself. ExampleThe <!-- Welcome page for MyWebApp --> <HTML> <HEAD><TITLE>Welcome to MyWebApp </TITLE></HEAD> <BODY><H1>Welcome to MyWebApp</H1> <FORM ACTION="/SASStoredProcess/do"> Please enter your first name: <INPUT TYPE="text" NAME="FNAME"><BR> <INPUT TYPE="hidden" NAME="_program" VALUE="/WebApps/MyWebApp/Ask Color"> <INPUT TYPE="submit" VALUE="Run Program"> </FORM> </BODY></HTML> This page prompts the user for a first name and passes the value as the FNAME input parameter to the /* Ask Color stored process * * This stored process prompts for the user's favorite * and passes it to the Print Color stored process. */ data _null_; file _webout; put '<HTML>'; put '<H1>Welcome to MyWebApp</H1>'; /* Create reference back to the Stored Process Web Application from special automatic macro variable _URL. */ put "<FORM ACTION='&_URL'>"; /* Specify the stored process to be executed using the _PROGRAM variable. */ put '<INPUT TYPE="hidden" NAME="_program" ' || 'VALUE="/WebApps/MyWebApp/Print Color">'; /* Pass first name value on to next program. The value is user entered text, so you must encode it for use in HTML. */ fname = htmlencode("&FNAME", 'amp lt gt quot'); put '<INPUT TYPE="hidden" NAME="fname" VALUE="' fname +(-1) '"><BR>'; put 'What is your favorite color?'; put '<SELECT SIZE=1 NAME="fcolor">'; put '<OPTION VALUE="red">red</OPTION>'; put '<OPTION VALUE="green">green</OPTION>'; put '<OPTION VALUE="blue">blue</OPTION>'; put '<OPTION VALUE="other">other</OPTION>'; put '</SELECT><BR>'; put '<INPUT TYPE="submit" VALUE="Run Program">'; put '</FORM>'; put '</HTML>'; run; This stored process simply creates an HTML form prompting the user for more information. The reserved macro variable _URL is used to refer back to the SAS Stored Process Web Application. This enables you to move the Web application without modifying each stored process. The _PROGRAM variable specifies the stored process that will process the contents of the form when it is submitted. In order to keep the FNAME that was entered in the initial page, place it in the form as a hidden field. Because the value was entered by the user, it must be encoded using the HTMLENCODE function in case it contains any character that might be interpreted as HTML syntax. The form prompts the user for a color choice and chains to a new stored process named /* Print Color stored process * * This stored process prints the user's * first name and favorite color. */ data _null_; file _webout; put '<HTML>'; fname = htmlencode("&FNAME"); put 'Your first name is <b>' fname +(-1) '</b>'; put '<BR>'; put "Your favorite color is <b>&FCOLOR</b>"; put '<BR>'; put '</HTML>'; run; The A variation of this technique uses URL parameters instead of hidden form fields. An alternate implementation of the /* Ask Color stored process * * This stored process prompts for the user's favorite * and passes it to the Print Color stored process. */ data _null_; file _webout; put '<HTML>'; put '<H1>Welcome to MyWebApp</H1>'; /* Build a URL referencing the next stored process. * Use URLENCODE to encode any special characters in * any parameters. */ length nexturl $500; nexturl = "&_URL?_program= /WebApps/MyWebApp/Print Color" || '&fname=' || urlencode("&FNAME"); put 'What is your favorite color?'; put '<UL>'; put '<LI><A HREF="' nexturl +(-1) '&color=red">red</A><LI>'; put '<LI><A HREF="' nexturl +(-1) '&color=green">green</A><LI>'; put '<LI><A HREF="' nexturl +(-1) '&color=blue">blue</A><LI>'; put '<LI><A HREF="' nexturl +(-1) '&color=other">other</A><LI>'; put '</UL>'; put '</HTML>'; run; This stored process generates a separate URL link for each color choice. The end result is the same as the first implementation of The technique of passing data by using hidden fields or URL parameters has the following advantages:
The major disadvantages of this technique are the necessity to use dynamically generated HTML for all pages in the application and the security and visibility of the data. The data in hidden fields is readily visible to the client by viewing the HTML source (and is directly visible in the URL when using GET method forms). The data is easily changed by the user and falsified or inconsistent data can be submitted to the application. Sensitive data should be validated in each new stored process, even if it is passed from generated hidden fields. Passing Data Through CookiesHTTP cookies are packets of information that are stored in the client Web browser. They are shuttled back and forth with the application requests. In a general sense, they are quite similar to hidden form fields, but they are automatically passed with every request to the application. Cookies have the advantage of being nearly invisible to the user. They contain a built-in expiration mechanism, and they are slightly more secure than hidden fields. They also work seamlessly across multiple stored process servers and Web applications and are preserved even if your application uses static HTML pages. See the HTTP Header documentation for more information about setting and using cookies. You must enable HTTP cookies in your Web application configuration. HTTP cookies can be complex to generate and parse. You must carefully consider names, paths and domains to ensure your cookie values do not conflict with other applications installed on the same Web server. HTTP cookies might also be disabled by some clients due to privacy concerns. Passing Data Through SessionsSessions provide a simple way to save state on the server. Instead of passing all of the saved information to and from the Web client with each request, a single session key is passed and the data is saved on the server. Applications must use all dynamically generated HTML pages, but the hidden fields or URL parameters are much simpler to generate. In addition, sessions provide a method to save much larger amounts of state information including temporary data sets or catalogs. Sessions have the disadvantage of binding a client to a single server process, which can affect the performance and scalability of a Web application. Sessions are not recommended for simple applications that pass small amounts of data from one stored process to another. See the sessions documentation for more information. |