This chapter introduces stored procedures, and describes how they work under OpenESQL and DB2.
A stored procedure is a compiled program that can execute SQL statements.
You need to use stored procedures if your application program operates in a client/server environment, and if either of the following two problems apply:
As we have seen above, a stored procedure is a compiled program that can execute SQL statements. Stored procedures are stored at a local or remote DB2 Universal Database Server. Local DB2 Universal Database Server applications or remote DRDA applications can use the SQL statement CALL to invoke a stored procedure.
Use stored procedures to combine many of your application's SQL statements into a single message to the DB2 subsystem or DB2 Universal Database Server, reducing network traffic to a single send and receive operation for a series of SQL statements.
Note: If you are running your stored procedure on DB2 for OS/390, through the DB2 Connect product, see your IBM DB2 documentation for other steps necessary to run the stored procedure.
To get a stored procedure up and running:
or
copy the COBOL run-time .dll (cblrtss.dll if using single threaded run-time ) to the directory from where the stored procedure will be executed. You need to do this for DB2 to be able to execute a COBOL stored procedure.
A stored procedure is an application program that runs in the DB2 Universal Database Server's address space. It can contain most statements that an application program normally contains. It can consist of more than one program. Your stored procedure can call other programs as well as nested stored procedures but there are restrictions. See the DB2 Universal Database Application Development Guide for details.
The application program that invokes the stored procedure can be in any language that supports SQL statements. You can write a stored procedure using many languages such as C, JAVA, COBOL or now SQL Procedure Language which is consistent with the Persistent Stored Module definition of the ANSI SQL99 standard.
The store procedure can be written in one language, for example JAVA, with the client written in another language, for example COBOL. When the languages differ, DB2 transparently passes the values between the client and the stored procedure so each program gets the values in the expected format defined by the CREATE PROCEDURE statement.
A stored procedure is similar to any other SQL application.
The following restrictions apply to stored procedures:
See the DB2 Universal Database Application Development Guide for a complete list.
The following are tasks which must be completed before a stored procedure can be run on an DB2 Universal Database Server:
A typical stored procedure contains two or more SQL statements, and some manipulative or logical processing. In this example, your application, CALLSTPR, runs on a workstation client and calls a stored procedure, GETEMPSVR. The following process occurs:
The application can call more stored procedures or it can execute more SQL statements. The application designer determines whether to COMMIT work in the stored procedure that runs on the server, or in the client as a single transaction.
To invoke a stored procedure and to pass a list of parameters to the procedure, use the SQL statement CALL. Your application program can call several stored procedures.
After connecting to its server, an application can mix calls to stored procedures with SQL statements sent to the server.
Use the CALL statement to execute each series of SQL statements in your application.
To call the stored procedure described in How an Application Works with a Stored Procedure, your application might use this statement:
EXEC SQL CALL GETEMPSVR (:V1, :V2) END-EXEC
If you use host variables in the CALL statement, you must declare them before using them.
The example above is based on the assumption that none of the input parameters can have null values. To allow null values, code a statement like this:
EXEC SQL CALL GETEMPSVR (:V1 :IV1, :V2 :IV2) END-EXEC
where :IV1 and :IV2 are indicator variables for the parameters.
To pass integer or character string constants or the null value to the stored procedure, code a statement like this:
EXEC SQL CALL GETEMPSVR (2, NULL) END-EXEC
To use a host variable for the name of the stored procedure, code a statement like this:
EXEC SQL CALL :PROCNAME (:V1, :V2) END-EXEC
Assume that the stored procedure name is GETEMPSVR. The host variable PROCNAME is a character variable of length 254 or less that contains the value GETEMPSVR. You should use this technique if you do not know in advance the name of the stored procedure, but you do know the parameter list convention.
To pass your parameters in a single structure, rather than as separate host variables, code a statement like this:
EXEC SQL CALL GETEMPSVR USING DESCRIPTOR :ADDVALS END-EXEC
where ADDVALS is the name of an SQLDA.
To use a host variable name for the stored procedure with an SQLDA, code a statement like this:
EXEC SQL CALL :PROCNAME USING DESCRIPTOR :ADDVALS END-EXEC
This form gives you extra flexibility because you can use the same CALL statement to invoke different stored procedures with different parameter lists.
Your client program must assign a stored procedure name to the host variable PROCNAME and load the SQLDA ADDVALS with the parameter information before making the SQL CALL statement.
Each of the above CALL statement examples uses an SQLDA. If you do not explicitly provide an SQLDA, the precompiler generates the SQLDA based on the variables in the parameter list.
You can execute the CALL statement only from an application program. You cannot use the CALL statement dynamically.
When an application executes the CALL statement, the DB2 Universal Database Server builds a parameter list for the stored procedure, using the parameters and values provided in the statement. The DB2 Universal Database Server obtains information about parameters from the system tables. See the section Defining Stored Procedures under DB2 Universal Database for more information. Parameters are defined as one of these types:
Input-only parameters, which provide values to the stored procedure.
Output-only parameters, which return values from the stored procedure to the calling program.
Input/output parameters, which provide values to or return values from the stored procedure.
If a stored procedure fails to set one or more of the output-only parameters, the DB2 Universal Database Server simply returns the output parameters to the calling program, with the values established on entry to the stored procedure. COBOL supports three parameter list conventions. Other languages support other conventions. The parameter list convention is chosen based on the parameter style defined in the CREATE PROCEDURE statement.
Parameter Style | Description |
---|---|
SIMPLE | Use SIMPLE (or GENERAL) to prevent the calling program passing null values for input parameters (IN or INOUT) to the stored procedure. The stored procedure must declare a variable for each parameter passed in the CALL statement. |
SIMPLE WITH NULLS | Use SIMPLE WITH NULLS (or GENERAL WITH NULLS) to allow the
calling program to supply a null value for any parameter passed to the stored
procedure. The following rules apply:
|
DB2SQL | In addition to the parameters on the CALL statement, the
following arguments are passed to the stored procedure:
|
If any of your output parameters require a lot of storage, do not pass the entire storage areas to your stored procedure, but declare an indicator variable for every large output parameter in your SQL statement CALL. Indicator variables are used in the calling program to pass only a two-byte area to the stored procedure and to receive the entire area from the stored procedure.
Note: If you are using the SIMPLE WITH NULLS linkage convention, you must declare indicator variables for all of your parameters, so you do not need to declare another indicator variable for the large output parameters.
Assign a negative value to each indicator value associated with a large output variable. Then include the indicator variables in the CALL statement. This technique can be used whether the stored procedure linkage is SIMPLE or SIMPLE WITH NULLS.
For example, suppose that a stored procedure, STPROC2 defined with the SIMPLE linkage convention takes one integer input parameter and one character output parameter of length 5000. It is wasteful to pass the 5000 byte storage area to the stored procedure. Instead, a COBOL program containing these statements passes only two bytes to the stored procedure for the output variable and receives all 5000 bytes from the stored procedure:
INNUM PIC S9(9) COMP OUTCHAR PIC X(5000) IND PIC S9(4) COMP . . . MOVE -1 TO IND EXEC SQL CALL STPROC2(:INNUM, :OUTCHAR :IND) END-EXEC
A stored procedure must declare each parameter passed to it1 . In addition, the PARMLIST column in the DECLARE PROCEDURE must contain a compatible SQL data type declaration for each parameter. For PARMLIST string and corresponding language declarations, see the SQL data types table in the Net Express Database Access manual.
For example:
CREATE PROCEDURE GETEMPSVR (IN EMPNO CHAR(6), INOUT SQLCD INT , OUT FIRSTNME CHAR(12), OUT LASTNAME CHAR(12), OUT HIREDATE CHAR(10), OUT SALARY DEC(9,2) ) LANGUAGE COBOL EXTERNAL NAME 'GETEMPSVR!GETEMPSVR' PARAMETER STYLE DB2SQL;
IBM has not implemented the same support for all SQL syntax related to stored procedures in every supported language. For example, you cannot create COBOL stored procedures that use result sets or the EXEC SQL syntax that supports that functionality with the workstation version of DB2 Universal Database. This might change in the future. See the DB2 Universal Database SQL Reference and the DB2 Application Development Guide for details of which functions are supported and by what language.
There is no support for structure, array, or vector parameters using the DB2 native precompiler. However, there is much more flexibility when using the OpenESQL precompiler and a ODBC connection. See the Net Express Database Access manual for more details.
A stored procedure is unusable until it is defined 1 - use the CREATE PROCEDURE command to do this. You can either use the DB2 command prompt or place the command in a program and compile and run it. If you use the DB2 command prompt, you first connect to the DB2 Universal Database Server where the stored procedure will be executed.
For example:
C:> db2 connect to sample
You can type in the command at the DB2 command prompt making sure you include continuation characters and command delimiters, or you can place the CREATE PROCEDURE in an ANSI text file. For example, if we placed the previous command in text file creproc.sql, the command that you would enter would be:
C:> db2 -td; -vf creproc.sql
where:
The create procedure statement must uniquely identify a stored procedure. If you want to change the stored procedure to either add or drop parameters or change functionality, you must use the DROP PROCEDURE command and then re-add it with the CREATE PROCEDURE command.
1 When DB2/2 was originally developed, DB2/2 did not support the CREATE PROCEDURE function, and it is possible to write COBOL stored procedures without doing a CREATE PROCEDURE. Examples of this method and the parmlist that is required are included in the DB2 Universal Database Application Development Client.
To compile a COBOL stored procedure using Net Express and DB2 Universal Database, follow the steps below:
Note that if your program contains stored procedure CALL statements, you must specify the CALL_RESOLUTION DB2 directive or an SQL0204 error will occur.
Because debugging a stored procedure by its very nature implies stopping the server and stepping through the server code, it is imperative that the programmer debugging the stored procedure code is the only person using the database server. You should therefore debug DB2 Universal Database stored procedures using a database on your own workstation if possible.
You can test a COBOL stored procedure without coding a client program by using:
If you don't get the expected results, you might want to debug the COBOL stored procedure. If you are running Net Express under Windows 9x, you can just add a call to CBL_DEBUGBREAK to your stored procedure and the Net Express debugger will display when the statement is executed.
If you are running under Windows NT / 2000 / XP, DB2 stored procedures are executed under the db2dari process for versions previous to DB2 UDB version 8, and executed under the db2fmp process for versions DB2 UDB version 8 or later, which means that a call to CBL_DEBUGBREAK will not work by itself. You need to compile the stored procedure with a "sleep" function and attach to a running process. When the CBL_DEBUGBREAK window is displayed, reply "NO" since replying "YES" will fail.
Note that you need to attach to the db2dari or db2fmp process before the sleep function expires or you will not be able to animate the stored procedure. If this happens, you will have to repeat the whole process described below so it is important to pick a suitably large sleep value.
To set a sleep value, define a variable in Working-Storage that will define how long to put the variable to sleep. The call to the sleep function can be placed either before or after the call to CBL_DEBUGBREAK.
For example:
01 ws-wait pic 9(8) comp-5 value 30000.
Then in the program add this statement so that it executes before you want to start animating:
call DB2API 'Sleep' using by value ws-wait
where DB2API is defined as call-convention 74 in a Special Names paragraph.
To animate the stored procedure:
You must have Administrator authority to attach a debugger to a running process.
When you have completed debugging the stored procedure, just exit from the Animator.
Tip: If the stored procedure is not working as expected, make sure the parameters passed to the stored procedure are getting passed in the expected format by examining each parameter in the Linkage Section.
Copyright © 2006 Micro Focus (IP) Ltd. All rights reserved.