Top Previous Next TOC Index

The PL/SQL Agent


The WebServer employs the PL/SQL Agent to execute PL/SQL procedures stored in the database. If you install the PL/SQL Developer's Toolkit with your PL/SQL Agent, you can use a set of predefined PL/SQL packages to generate HTML formatted output, leaving you free to focus on the logic of your application. Even using the PL/SQL Developer's Toolkit, you need a conceptual understanding of HTML. For example, you must know at what points in your page anchors are necessary, although you needn't write the actual code for the anchors. The PL/SQL Agent takes care of interfacing to the needed environment variables and generating the HTML code.


Database Connection Descriptors (DCDs)

Whenever a URL invokes the PL/SQL Agent, it specifies a DCD. Creating and maintaining the DCDs is the responsibility of the WebServer administrator. As an application developer, all you need be concerned with is generating URLs that specify the correct DCD to achieve the result you want. The following is the information the DCD provides:

username
All SQL and PL/SQL statements are executed by the database under the auspices of some database user. This name identifies that user. The username determines the schema (logical section of a database) that the PL/SQL Agent connects to, the actions it can perform, the resources (disk space and so on) it can use, and the level of monitoring of its activities that the database performs.
password
This is provided if you want to password protect the DCD, ensuring that only certain people connect as the user identified by username. Keep in mind, however, that the users who connect to the database as username still will be able to do only what the application gives them the ability to specify through URLs.
ORACLE_HOME
This is the root of the Oracle7 Server code tree in the OS file system.
ORACLE_SID
If the PL/SQL Agent is to connect to a local database, this determines that database. If the WRB is used, the request will be handed off to a process connected already to this database, if possible
SQL*Net V2 Service Name or Connect String
If the PL/SQL Agent is to connect to a remote database, this determines that database.
owa_err_page
This is the pathname of the HTML document that the PL/SQL Agent is to return to the client's browser when an error occurs in the PL/SQL procedure that the PL/SQL Agent invoked. This is the actual path as understood by the OS, not the virtual path as configured in the Web Listener
owa_valid_ports
The valid Web Listener network ports to which the PL/SQL Agent will respond. The network port is, of course, specified in the URL. You must make sure that the URLs your applications generate provide port numbers that are valid for the WRB Service or CGI program they specify.
owa_log_dir
The directory where the PL/SQL Agent writes its error file. The error file differs from the page in that it is for the WebServer administrator's attention, rather than the clients.
owa_nls_lang
The NLS_LANG of the Oracle7 database to which the PL/SQL Agent connects. If not specified, the PL/SQL Agent administration program looks up the database NLS_LANG when the service is submitted. The NLS_LANG indicates the language to be used.

How the PL/SQL Agent Uses Environment Variables

Note: These are CGI standard environment variables. However, the PL/SQL Agent can use them whether it is invoked through CGI or through the Web Request Broker (WRB).

The PL/SQL Agent uses the environment variables shown below:

Variable
Contains
REQUEST_METHOD

GET or POST

PATH_INFO

the name of PL/SQL procedure to invoke

SCRIPT_NAME

contains the DCD the PL/SQL 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.)

CGI Variables Used by the Oracle PL/SQL Agent


Passing Parameters to PL/SQL

A PL/SQL procedure usually 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 PL/SQL Agent

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

It is transparent to the PL/SQL procedure that is the actual consumer of these parameter(s) which method is used to pass the parameters from the Web Listener to the PL/SQL Agent and which protocol, the WRB or CGI, is used. This is an important feature of the Oracle PL/SQL Agent: the PL/SQL programmer need not be aware of whether GET or POST 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 PL/SQL 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 does the same thing as the previous example, except that instead of populating the QUERY_STRING environment variable with "person=Gretzky," the Web Listener writes "person=Gretzky" to standard input.

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;


Providing Default Parameter Values

If you cannot guarantee that a value will be passed from a Web Browser for a particular PL/SQL procedure parameter, then you should 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;

Suppose the PL/SQL Agent receives a request to call procedure showvals with no value for "a" and the value of 'Hello' for "b", and there was no DEFAULT NULL clause in 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


Multivalued Parameters

Generally, you need not be concerned with the order in which the Oracle PL/SQL Agent receives parameters from a URL. The only case where it might be relevant is when passing multiple values for the same form field. In this case, all the values for that form field should be together, and if the order of the values in that field is significant, that order must be preserved in the URL.

There are a number of instances where you can have such multiple values for the same HTML variable. The HTML tag "SELECT" allows users to select from a set of possible values for an HTML form field. If the SIZE parameter of that SELECT tag is greater than one, the form allows multiple selection, and the user can choose to select more than one value. For example, if you ask a user to indicate her hobbies, she may well have more than one. In this case, you pass the multiple values to a single PL/SQL parameter, which must be a PL/SQL table. A PL/SQL table is a data structure similar to an array.


Example of a Multivalued Field

Another case where one has a set of values corresponding to a single form field is shown in this example:

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 brings up a page that looks like this:

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 the following:

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

Note that the PL/SQL Agent can only pass parameters to PL/SQL tables that 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 32K (32767 bytes). The values can then be explicitly converted to NUMBER, DATE, or LONG within the stored procedure (using TO_NUMBER or TO_DATE - no conversion needed for LONGs).


Overloading Procedures

As explained in the Overview of the Oracle7 Server, SQL, and PL/SQL under Overloading Subprograms, PL/SQL allows you to overload procedures and functions that are in PL/SQL packages. In overloading, multiple procedures or functions have the same name, but are distinguished by the fact that they take different parameters. 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;

Note: The PL/SQL Agent can use this functionality with the following restriction: if two procedures take the same number of parameters, those parameters must differ in name as well as datatype (normally a difference in datatype suffices to distinguish the parameters). For example:

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

If executed directly from SQL, this would be acceptable, but when the PL/SQL Agent attempts to determine which procedure to call, it is not able to distinguish between the two and will generate an error.

This limitation is imposed by the lack of HTML form datatypes


Oracle PL/SQL Agent Error Handling

There are two types of errors that the Oracle PL/SQL Agent handles:


Application Errors

Application errors are specific to the PL/SQL application. All PL/SQL procedures you write should have their own exception handling (see Handling Exceptions) that produces the appropriate output in HTML form.

Because the PL/SQL Agent does not read the HTML output to determine its content, and properly handled exceptions themselves generate HTML error messages, handled exceptions are transparent. As far as the PL/SQL Agent is concerned, if the PL/SQL code generates HTML output, the operation was successful. The user will see whatever handled exception message is generated by the PL/SQL procedure.


System Errors

System errors are detected by the Oracle PL/SQL Agent itself. These are errors that occur when the PL/SQL Agent is unable to launch the PL/SQL procedure or when a PL/SQL exception is not handled by the stored procedure, causing the exception to be propagated back to the PL/SQL Agent as a system error. This causes a standard HTML error document to be returned to the browser.

For example, if the Oracle PL/SQL Agent cannot make a connection to the Oracle7 Server, the PL/SQL procedure cannot run and a system error occurs. The PL/SQL Agent then returns a default error message to the browser or returns a customized HTML error page (if one was previously configured as part of the DCD using the OWA_ERR_PAGE parameter).


Click Here to Go to the top of the section.

Click Here to Go to the previous topic.

Click Here to Go to the next topic.

Click here to Go to the Table of Contents.

Click here to Go to the Index.


This document was last modified at 03:55pm PST on March 27, 1996.

To report any problems or comments, e-mail Oracle WebServer Documentation.