Page 1227
The HTP and HTF packages are similar. In fact, there is a one-to-one correspondence between their respective functions and procedures. The rule that dictates when to use HTF instead of HTP is as follows : You always use the HTP procedures unless the call is embedded. In other words, if a single line of code references more than one call to these routines, the innermost calls must all be HTF functions.
The code examples show how to use the HTF and HTP packages. The first example makes a single call to the HTML routines, so it calls the HTP procedure:
htp.print (`This is a line of text');
The output looks like this:
This is a line of text
The second example makes two calls to the HTML routines, so the inner call uses the HTF package and the outer call uses the HTP package:
htp.print (htf.bold (`This is a bolded line of text'));
The output looks like this:
<B>This is a bolded line of text</B>
Several categories each have multiple functions and procedures within the HTP and HTF packages:
The OWA_UTIL package provides procedures and functions to read CGI environment variables , generate dynamic SQL, and format dates and times.
Page 1228
The OWA_PATTERN package provides powerful regular expression pattern-matching capabilities. A regular expression is a format string containing metacharacters, which yields a powerful method of filtering information. Table 54.2 provides a few examples.
Table 54.2. Regular expression examples provided with the OWA pattern package.
Regular Expression | Description | Example |
^Web | Matches values that begin with Web | Web Page |
Web | Matches values that contain Web | A Web Page |
\d\d.\d\d.\d\d | Matches values that look like a date | 12/25/97 or 12-25-97 |
^\W | Matches values that begin with non-word characters | # This is a remark |
The complexity of the regular expression can grow exponentially from here. The preceding examples are trivial. You can see how this kind of functionality can add a great deal of intelligence to a Web application.
The OWA_COOKIE package provides the PL/SQL programmer with the capability to send and get cookies with a client process. A cookie is used as a method of maintaining a context for a client. This enables the client to maintain state information between URL requests . Cookies are typically saved to temporary storage such as a fixed disk.
The code examples use some of the capabilities of the PL/SQL cartridge and utilities to create a response to a request for a dynamic Web page. The following procedure shows how to implement a relatively simple set of PL/SQL calls to create a dynamic Web page that contains an HTML table:
create or replace procedure GetScottsTables AS bRet boolean; BEGIN htp.htmlopen; htp.headopen; htp.title(`Scott/Tiger Tables'); htp.headclose; htp.bodyopen;
Page 1229
htp.header(1, `Scott/Tiger Tables'); bRet := owa_util.tableprint(`cat', `BORDER'); htp.bodyclose; htp.htmlclose; END;
This routine is obviously for illustration purposes only; it has no other value. The output looks similar to the following:
Scott/Tiger Tables TABLE_NAME TABLE_TYPE CUSTOMER TABLE DEPT TABLE EMP TABLE
The procedure takes advantage of the HTP package to deal with the details of formatting the HTML tag language. The call to owa_util.tableprint prepares the table with a border. The tableprint function has many variations for customizing the output. One of its parameters is an ordered column list to display the output. The preceding example used the default column list of *.
The next procedure in Listing 54.1 illustrates how values can be accepted through the Web server and an update can be applied to the database.
Listing 54.1. Accepting information over the Web and updating a database.
/* This procedure allows customers to update their names */ create or replace procedure UpdateCustName ( key in varchar2 , NewCustName in varchar2 ) AS BEGIN htp.htmlopen; htp.headopen; htp.title(`Update of Customer'); htp.headclose; htp.bodyopen; htp.header(1, `Update of Customer'); /* Actual Update Statement */ update customer set cust_name = NewCustName where cust_id = key ; commit; /* If the Update fails, processing will never reach this point, but instead an exception will be raised */ htp.print (`Customer update successful'); htp.bodyclose; htp.htmlclose; END;
Page 1230
This procedure is obviously simplified to expect no errors. In a real-world application, more overhead such as exception handling should be in place.
The true power of the Web Application Server is realized using the C language to create a Web application. This does not exclude the use of PL/SQL or SQL. In fact, the approach of using C combined with the Pro*C precompiler offers many possibilities.
Listing 54.2 illustrates a simple C cartridge that responds to an HTTP request to display the text "Hello, world!".
Listing 54.2. A cartridge stub that responds to an HTTP request.
/* File: Hello_WRB.c */ #ifndef ORATYPES_ORACLE /* Include OraTypes header file */ #include <oratypes.h> #endif #include <wrb.h> WRBReturnCode Hello_Init(); WRBReturnCode Hello_Auth(); WRBReturnCode Hello_Exec(); WRBReturnCode Hello_Shut(); WRBReturnCode Hello_entry (WRBCalls) WRBCallbacks * WRBCalls; { /* Assign the handlers for the standard callbacks */ WRBCalls->init_WRBCallback = Hello_Init; WRBCalls->authorize_WRBCallback = Hello_Auth; WRBCalls->exec_WRBCallback = Hello_Exec; WRBCalls->shut_WRBCallback = Hello_Shut; return (WRB_DONE); } WRBReturnCode Hello_Init (WRBCtx, clientcxp) void * WRBCtx; void ** clientcxp; { return (WRB_DONE); } WRBReturnCode Hello_Auth (WRBCtx, clientcxp, bAuthorized) void * WRBCtx; void * clientcxp;