Oracle WebServer User's Guide

Contents Index Home Previous Next

How the Oracle Web Agent Works

The Oracle Web Agent enables you to create PL/SQL stored procedures that can access data in Oracle7, dynamically create an HTML document from that data using the Developer's Toolkit, and return that document to the client.

This is a step by step description of how the Oracle Web Agent works:

Web Agent Service

Since it is desirable that a single Web Listener be able to access multiple databases or schemas within a database, the Oracle Web Agent supports the concept of services. For more information on databases and schemas, see Chapter 4 of this manual. The concept of services is best described by an example:

Company A would like data stored in its Oracle7 database to be accessible to the public via an Oracle Web Listener. However, different departments within Company A have access to different parts of the database (schemas), which are partitioned by way of user names. Thus, the Human Resources department and the Accounts Payable department use different username/password combinations to log on to the database. If both want to write CGI applications using the Oracle Web Agent to access their data, the Web Agent needs to use the correct username/password when it logs on to the database. In this scenario, the owa.cfg file, which contains the configuration information, will contain two services, an HR service, and an AP service. Each service will have an associated username/password, an ORACLE_HOME parameter, and an ORACLE_SID parameter. When a request from a Web browser comes in, the Web Listener will extract the service name that is embedded in the URL and find out which parameters to use by reading the owa.cfg file.

To connect to the Oracle7 Server, the Web Agent needs the following information to be specified in the Web Agent service:

The Administration Utility allows the administrator to display, create, modify or delete a Web Agent service. With the Web Agent Creation form, you do not need to modify the configuration file for the Oracle Web Agent service (owa.cfg) directly. See the section "Creating or Modifying Web Agent Services,"[*] for more information.

The following is an example of a Web Agent service entry in the owa.cfg file, and a corresponding explanation for each parameter:

 Developer's T#

(
owa_service = es
(
owa_user = www_es
)
(
owa_password = tiger 
)
(
oracle_home = /opt/oracle7
)
(
oracle_sid = esprod
)
(
owa_err_page = /es_err.html
)
(
owa_valid_ports = 8000 8888
)
(
owa_log_dir = /opt/oracle7/ows/log
)
(
owa_nls_lang = AMERICAN_AMERICA.US7ASCII
)
)

owa_service
Name of the Web Agent service

owa_user
Database username that the Web Agent will use to connect to the database.

owa_password
Database password that the Web Agent will use to connect to the database.

oracle_home
The location of the Oracle7 code tree in the file system. This should be the ORACLE_HOME for the database to which this Web Agent service connects, unless the Web Agent service is set up to connect to a remote database (over SQL*Net). In that case, specify the ORACLE_HOME where the Web Agent is installed. The Web Agent is always installed in an ORACLE_HOME directory or some subdirectory thereof.

oracle_sid
Name of the database system ID to connect to. Does not apply for connections to a remote database.

owa_err_page
This is the path of the HTML document that is returned by the Web Agent when an error occurs in the PL/SQL procedure that the Web Agent invoked. This is the actual path, not the virtual path as configured in the Web Listener.

owa_valid_ports

The valid Web Listener network ports the Web Agent will service.

owa_log_dir
The directory where the Oracle Web Agent writes its error file. The error file will have the name service_name.err.

owa_nls_lang

The NLS_LANG of the Oracle7 database to which the Web Agent connects. If not specified, the Web Agent administration program looks up the database NLS_LANG when the the service is submitted.

How the Web Agent Uses CGI Environment Variables

The Web Agent uses the environment variables shown in Table 5 - 1:

Variable Contains
REQUEST_METHOD GET or POST
PATH_INFO the name of PL/SQL procedure to invoke
SCRIPT_NAME contains the service the Web Agent is to use when logging on to Oracle7
QUERY_STRING parameters to the PL/SQL procedure (for GET method only. POST method parameters are passed via standard input.)
Table 5 - 1. CGI Variables Used by the Oracle Web Agent

The following is an example of how a typical URL is parsed by the Web Listener in compliance with the CGI 1.1 specification.

http://www.nhl.com:8080/ows-bin/nhl/owa/hockey.pass?person=Gretzky

Note: The fact that the QUERY_STRING environment variable is used indicates that this is a GET request. You can also pass parameters using the POST method. For an example of how to pass parameters using the POST method, please see the next section, "Passing Parameters to PL/SQL".

Passing parameters to PL/SQL

A PL/SQL procedure often requires parameters in order to execute and generate the appropriate HTML document. The following section discusses several key concepts and tips that a PL/SQL developer should understand with respect to how parameters get passed to the specified PL/SQL routine.

These key concepts and tips are:

Getting Parameters from the Web Browser to the Web Agent

Depending on the REQUEST_METHOD used, parameters are passed from the Web Browser to the Web Listener to the Web Agent in one of two ways:

The method used to pass parameters from the Web Listener to the Web Agent is transparent to the PL/SQL procedure that is the actual consumer of the parameter(s). This is an important feature of the Oracle Web Agent: the PL/SQL programmer need not be aware of which method is used and need not be concerned with parsing either the QUERY_STRING environment variable or standard input. Thus, the PL/SQL programmer can concentrate on what he or she knows best: developing the logic to extract data from the Oracle database, based on pre-parsed parameters passed by the Oracle Web Agent.

It is recommended that you use POST whenever possible. GET is the method used for links and non-form URLs. For HTML forms, one has a choice. Because the GET method uses operating system environment variables, there are limits on the length of the QUERY_STRING.

Passing Parameters Using an HTML Form

The following example is analogous to the one in the previous section, except that it uses an HTML form that employs the POST REQUEST_METHOD.

<FORM METHOD="POST" ACTION="http://www.nhl.com:8080/ows-bin/nhl/owa/hockey.pass">
Please type the name of the person you wish to search for:
<INPUT TYPE="text" NAME="person"><P>
To submit the query, press this button: 
<INPUT TYPE="submit" VALUE="Submit Query">. <P>
</FORM>

The above form will cause the Oracle Web Listener to behave in the same fashion as the previous example, except that instead of populating the QUERY_STRING environment variable with "person=Gretzky," the Web Listener will write "person=Gretzky" to standard input. This assumes, of course, user typed "Gretzky" in the entry field of the HTML form above.

Note that the name of the HTML input variable, in this case "person", has to be the same as the PL/SQL parameter it is to match.

The PL/SQL procedure that is the recipient of the above parameters follows:

create or replace
procedure hockey_pass (person in varchar2) is
   n_assists integer;
begin
   select num_assists into n_assists
      from hockey_stats
   where name=person;
   htp.print(person||' has '||to_char(n_assists)||' assists this      season');
end;

Ordering Parameters

Generally, the PL/SQL developer does not need to be concerned with the order in which the Oracle Web Agent receives parameters from an HTML form or through a URL. The only case that it will be relevant is when passing multiple values for the same form field. See "Using Multiple HTML Form Fields with the Same Name" later in this section.

Defaulting Parameter Values

If the PL/SQL developer cannot guarantee that a value will be passed from a Web Browser for a particular PL/SQL procedure parameter, then it is recommended that he or she give the parameter a default value. For example:

create or replace procedure showvals(a in varchar2 DEFAULT NULL,
                                     b in varchar2 DEFAULT NULL) 
is 
begin 
   htp.print('a = '||a||htp.br);
   htp.print('b = '||b||htp.br); 
end; 

If the Web Agent were to receive a request to call procedure showvals where there was no value for "a", the value for "b" was, say, "Hello", and the DEFAULT NULL clause was not part of the procedure's definition, then the request would generate an error with the following message:

OWS-05111: Agent : no procedure matches this call
  OWA SERVICE: test_service 
  PROCEDURE: showvals 
 PARAMETERS: 
  =========== 
  B: 
   Hello 

By "defaulting" the parameters, the above request would properly output:

a = <BR> 

b = Hello<BR> 

which to the end user would look like:

a = 
b = Hello 

Using Multiple HTML Form Fields with the Same Name

There are a number of instances where one would want to have multiple values passed for the same HTML form variable, and hence to the same PL/SQL parameter. To handle this situation, one can use PL/SQL tables to create an array of values.

One case where multiple values are passed with the same HTML form variable name is in the use of the HTML form tag "SELECT". If one sets the SIZE parameter to something greater than 1, then the user will be able to select multiple values for the same form field.

Another case where one has a set of values corresponding to a single form field follows:

-- QUERY_FORM prints an HTML page with all the columns for the   
-- specified table.  Invoke the procedure from a Web Browser with
-- a URL like:
http://yourhost:port_num/service_name/owa/query_form?the_table=emp

create or replace procedure query_form(the_table in varchar2) is  
   cursor cols is 
   select column_name   
       from user_tab_columns 
   where table_name = upper(the_table); 
begin
   htp.htmlOpen; 
   htp.headOpen; 
   htp.htitle('Query the '||the_table||' table!'); 
   htp.headClose; 
   htp.bodyOpen; 
   -- Use owa_util.get_owa_service path to automatically retrieve 
   htp.formOpen(owa_util.get_owa_service_path||'do_query');
   -- Put in the table as a hidden field to pass on to do_query   
   htp.formHidden('the_table', the_table);
   -- Put in a dummy value, as we cannot DEFAULT NULL a PL/SQL    
   table. 
htp.formHidden('COLS', 'dummy'); 
   for crec in cols loop
      -- Create a checkbox for each column. The form field name   
      -- will be COLS and the value will be the given column name.
      -- Will need to use a PL/SQL table to retrieve a set of 
      -- values like this. Can use the owa_util.ident_arr type    
      -- since the columns are identifiers.
      htp.formCheckbox('COLS',crec.column_name); 
      htp.print(crec.column_name); 
      htp.nl; 
   end loop; 
   -- Pass a NULL field name for the Submit field; that way, a 
   -- name/value pair is  not sent in.  Wouldn't want to do this  
   -- if there were multiple submit buttons.
   htp.formSubmit(NULL, 'Execute Query');    
   htp.formClose; 
   htp.bodyClose; 
   htp.htmlClose; 
end;

Invoking this procedure will bring up a page which looks like:

In this example, the user has already selected to query the EMPNO, ENAME, JOB, and SAL columns:

Here is a procedure to process this form submission:

-- DO_QUERY executes the query on the specified columns and 
-- tables.The OWA_UTIL.IDENT_ARR datatype is defined as: 
--  -- type ident_arr is table of varchar2(30) index by binary_integer
-- create or replace procedure do_query(the_table in varchar2, 
                                    cols in owa_util.ident_arr) is

   column_list varchar2(32000); 
   col_counter integer;
   ignore      boolean;
begin 
-- For PL/SQL tables, have to just loop through until you hit 
-- no_data_found. Start the counter at 2 since we put in 
-- a dummy hidden field. 
   col_counter := 2; 
   loop 
      -- build a comma-delimited list of columns 
      column_list := column_list||cols(col_counter)||','; 
      col_counter := col_counter + 1; 
   end loop; 
exception 
   when no_data_found 
   then 
       -- strip out the last trailing comma 
       column_list := substr(column_list,1,length(column_list)-1); 
        -- print the table - assumes HTML table support 
       ignore := owa_util.tablePrint(the_table, 'BORDER', 		
							OWA_UTIL.HTML_TABLE,
 column_list); 
end; 

Then after selecting the "Execute Query" button, the user would see:

It is a good idea to use a hidden place-holder variable as the first value if you cannot guarantee that at least one value will be submitted for the PL/SQL table. The reason is that one cannot DEFAULT a PL/SQL table. And a call to this procedure with just one argument (the_table) would cause the Web Agent to generate an error.

Note that the Web Agent can only pass parameters to PL/SQL tables which have a base type of VARCHAR2. This should not provide a significant limitation, as the PL/SQL type VARCHAR2 is the largest PL/SQL datatype with a maximum length of 32767 bytes. The values can then be explicitly converted to NUMBER, DATE, or LONG within a stored procedure (using TO_NUMBER or TO_DATE - no conversion needed for LONGs).

Overloading Procedures

PL/SQL allows developers to overload procedures and functions that are in PL/SQL packages (but not standalone functions and procedures, For a discussion of overloading as implemented in PL/SQL, see "Overloading Subprograms"[*] of this manual). For example:

create or replace package overload is 
     procedure proc1(charval in varchar2); 
     procedure proc1(numval  in number); 
end; 
 
create or replace package body overload is 
     procedure proc1(charval in varchar2) is 
     begin 
        htp.print('The character value is '||charval); 
     end; 
 
     procedure proc1(numval  in number); 
        htp.print('The number value is '||numval); 
     end; 
end; 

This functionality can be utilized by the Web Agent, but with the restriction that procedures that are overloaded on datatypes should not have the same parameter names. For example:

create or replace package overload is 
     procedure proc1(val in varchar2); 
     procedure proc1(val in number); 
end; 

When the Web Agent attempts to determine which procedure to call, it will not be able to distinguish between the two and will generate an error.

This limitation is imposed by the lack of HTML-form datatypes, but should not provide a significant limitation, as the PL/SQL type VARCHAR2 is the largest PL/SQL datatype with a maximum length of 32767 bytes. The values can then be explicitly converted to NUMBER, DATE, or LONG within a stored procedure (using TO_NUMBER or TO_DATE - no conversion needed for LONGs).

Accessing CGI Environment Variables

The Oracle Web Listener conforms to the Common Gateway Interface (CGI) 1.1 specification. Thus, all CGI environment variables that are part of this specification are passed from the Oracle Web Listener to the Web Agent. The Web Agent, in turn, makes all relevant environment variables accessible from within PL/SQL.

The Web Agent makes available the CGI environment variables shown in Table 5 - 2.

Variable Variable Meaning
AUTH_TYPE Method used to validate user
GATEWAY_INTERFACE The revision of the CGI specification to which the server complies
HTTP_USER_AGENT The browser the client is using to send the request
PATH_INFO Extra path information given by the client
PATH_TRANSLATED Translated version of PATH_INFO provided by server for mapping. This consists of the document root concatenated to the PATH_INFO.
REMOTE_HOST Hostname making the request if it can be determined
REMOTE_ADDR IP address of the remote host making the request
REMOTE_USER Used to authenticate user
REMOTE_IDENT Set to the remote username retrieved from the server
SERVER_PROTOCOL Name and revision of the information protocol used in the request
SERVER_SOFTWARE Name and version of information server software answering the request
SERVER_NAME The server's hostname, or IP address
SERVER_PORT Port number on which the server is running
SCRIPT_NAME Virtual path to the script being executed, used for self-referencing URL
Table 5 - 2. CGI Environment Variables

These environment variables can be accessed from within PL/SQL using the owa_util.get_cgi_env function, which is documented[*],"The Oracle WebServer Developer's Toolkit".


Contents Index Home Previous Next