4.3 Using DRDA Server Stored Procedures with the Gateway
The procedural feature of the gateway enables invocation of native DRDA server stored procedures.
After the stored procedure is defined to the DRDA server, the gateway is able to use the existing DRDA server definition to run the procedure. The gateway does not require special definitions to call the DB2 stored procedure. Standard Oracle PL/SQL is used by the Oracle application to run the stored procedure.
In Figure 4-2, an Oracle application calls the empproc
stored procedure that is defined to the DRDA server (for example, DB2 UDB for z/OS).
Figure 4-2 Running DRDA Server Stored Procedures

Description of "Figure 4-2 Running DRDA Server Stored Procedures"
From the perspective of the application, running the DB2 stored procedure is no different from invoking a stored procedure at a remote Oracle database instance.
- Oracle Application and DRDA Server Stored Procedure Completion
For an Oracle application to call a DB2 stored procedure, it is first necessary to create the DB2 stored procedure on the DB2 system by using the procedures documented in the IBM reference document for DB2 SQL. - Procedural Feature Considerations with DB2
There are special considerations for using the procedural feature with the gateway. - Result Sets and Stored Procedures
The Oracle Database Gateway for DRDA provides support for stored procedures that return result sets.
Parent topic: Developing Applications
4.3.1 Oracle Application and DRDA Server Stored Procedure Completion
For an Oracle application to call a DB2 stored procedure, it is first necessary to create the DB2 stored procedure on the DB2 system by using the procedures documented in the IBM reference document for DB2 SQL.
After the stored procedure is defined in DB2, the gateway is able to access the data using a standard PL/SQL call. For example, an employee name, John Smythe
, is passed to the DB2 stored procedure REVISE_SALARY
. The DB2 stored procedure retrieves the salary value from the DB2 database in order to calculate a new yearly salary for John Smythe
. The revised salary that is returned as result is used to update the EMP
table of Oracle database:
DECLARE INPUT VARCHAR2(15); RESULT NUMBER(8,2); BEGIN INPUT := ‘JOHN SMYTHE'; REVISE_SALARY@DB2(INPUT, RESULT); UPDATE EMP SET SAL = RESULT WHERE ENAME = INPUT; END;
When the gateway receives a call to run a stored procedure on the DRDA server, it first does a lookup of the procedure name in the server catalog. The information that defines a stored procedure is stored in different forms on each DRDA server. For example, DB2 UDB for iSeries uses the tables QSYS2.SYSPROCS
and QSYS2.SYSPARMS
. The gateway has a list of known catalogs to search, depending on the DRDA server that is being accessed.
The search order of the catalogs is dependent on whether the catalogs support Location designators (such as LUNAME
in SYSIBM.SYSPROCEDURES
), and authorization or owner IDs (such as AUTHID
in SYSIBM.SYSPROCEDURES
or OWNER
in SYSIBM.SYSROUTINES
).
Some DRDA servers allow blank or public authorization qualifiers. If the DRDA server that is currently connected supports this form of qualification, then the gateway will apply those naming rules when searching for a procedure name in the catalog.
The matching rules will first search for a public definition, and then an owner qualified procedure name. For more detailed information, refer to the IBM reference document for DB2 SQL.
Parent topic: Using DRDA Server Stored Procedures with the Gateway
4.3.2 Procedural Feature Considerations with DB2
There are special considerations for using the procedural feature with the gateway.
For example:
- PL/SQL records cannot be passed as parameters when invoking a DB2 stored procedure.
- The gateway supports the
GENERAL
andDB2SQL
linkage conventions of DB2 stored procedures. Both linkage conventions require that the parameters that are passed to and from the DB2 stored procedure cannot be null.
Parent topic: Using DRDA Server Stored Procedures with the Gateway
4.3.3 Result Sets and Stored Procedures
The Oracle Database Gateway for DRDA provides support for stored procedures that return result sets.
By default, all stored procedures and functions do not return a result set to the user. To enable result sets, set the HS_FDS_RESULTSET_SUPPORT
parameter in the initialization parameter file.
See Also:
Initialization Parameters for information about editing the initialization parameter file and theHS_FDS_RESULTSET_SUPPORT
parameter. For further information about Oracle support for result sets in non-Oracle databases see Oracle Database Heterogeneous Connectivity User's Guide.
Note:
If you set theHS_FDS_RESULTSET_SUPPORT
gateway initialization parameter, you must change the syntax of the procedure execute statement for all existing stored procedures or errors will occur.
When accessing stored procedures with result sets through the Oracle Database Gateway for DRDA, you will be in the sequential mode of Heterogeneous Services. The gateway returns the following information to Heterogeneous Services during procedure description:
- All the input arguments of the remote stored procedure
- None of the output arguments
- One out argument of type ref cursor (corresponding to the first result set returned by the stored procedure)
Client programs have to use the virtual package function DBMS_HS_RESULT_SET.GET_NEXT_RESULT_SET
to get the ref cursor for subsequent result sets. The last result set returned is the out argument from the procedure.
The limitations of accessing result sets are as follows:
- Result sets returned by a remote stored procedure have to be retrieved in the order in which they were placed on the wire.
- On execution of a stored procedure, all result sets returned by a previously executed stored procedure will be closed, regardless of whether the data has been completely retrieved or not.
In the following example, the UDB stored procedure is executed to fetch the contents of the EMP
and DEPT
tables from UDB:
CREATE PROCEDURE REFCURPROC (IN STRIN VARCHAR(255), OUT STROUT VARCHAR(255) ) RESULT SETS 3 LANGUAGE SQL BEGIN DECLARE TEMP CHAR (20); DECLARE C1 CURSOR WITH RETURN TO CALLER FOR SELECT * FROM TKHOEMP; DECLARE C2 CURSOR WITH RETURN TO CALLER FOR SELECT * FROM TKHODEPT; OPEN C1; OPEN C2; SET STROUT = STRIN; END
- OCI Program Fetching from Result Sets in Sequential Mode
This example shows OCI program fetching from result sets in sequential mode. - PL/SQL Program Fetching from Result Sets in Sequential Mode
This example shows a PL/SQL program fetching from result sets in sequential mode.
Parent topic: Using DRDA Server Stored Procedures with the Gateway
4.3.3.1 OCI Program Fetching from Result Sets in Sequential Mode
This example shows OCI program fetching from result sets in sequential mode.
For example:
OCIEnv *ENVH; OCISvcCtx *SVCH; OCIStmt *STMH; OCIError *ERRH; OCIBind *BNDH[3]; OraText arg1[20]; OraText arg2[255]; OCIResult *rset; OCIStmt *rstmt; ub2 rcode[3]; ub2 rlens[3]; sb2 inds[3]; OraText *stmt = (OraText *) "begin refcurproc@UDB(:1,:2,:3); end;"; OraText *n_rs_stm = (OraText *) "begin :ret := DBMS_HS_RESULT_SET.GET_NEXT_RESULT_SET@UDB; end;"; /* Prepare procedure call statement */ /* Handle Initialization code skipped */ OCIStmtPrepare(STMH, ERRH, stmt, strlen(stmt), OCI_NTV_SYNTAX, OCI_DEFAULT); /* Bind procedure arguments */ inds[0] = 0; strcpy((char *) arg1, "Hello World"); rlens[0] = strlen(arg1); OCIBindByPos(STMH, &BNDH[0], ERRH, 1, (dvoid *) arg1, 20, SQLT_CHR, (dvoid *) &(inds[0]), &(rlens[0]), &(rcode[0]), 0, (ub4 *) 0, OCI_DEFAULT); inds[1] = -1; OCIBindByPos(STMH, &BNDH[1], ERRH, 1, (dvoid *) arg2, 20, SQLT_CHR, (dvoid *) &(inds[1]), &(rlens[1]), &(rcode[1]), 0, (ub4 *) 0, OCI_DEFAULT); inds[2] = 0; rlens[2] = 0; OCIDescriptorAlloc(ENVH, (dvoid **) &rset, OCI_DTYPE_RSET, 0, (dvoid **) 0); OCIBindByPos(STMH, &BNDH[2], ERRH, 2, (dvoid *) rset, 0, SQLT_RSET, (dvoid *) &(inds[2]), &(rlens[2]), &(rcode[2]), 0, (ub4 *) 0, OCI_DEFAULT); /* Execute procedure */ OCIStmtExecute(SVCH, STMH, ERRH, 1, 0, (CONST OCISnapshot *) 0, (OCISnapshot *) 0, OCI_DEFAULT); /* Convert result set to statement handle */ OCIResultSetToStmt(rset, ERRH); rstmt = (OCIStmt *) rset; /* After this the user can fetch from rstmt */ /* Issue get_next_result_set call to get handle to next_result set */ /* Prepare Get next result set procedure call */ OCIStmtPrepare(STMH, ERRH, n_rs_stm, strlen(n_rs_stm), OCI_NTV_SYNTAX, OCI_DEFAULT); /* Bind return value */ OCIBindByPos(STMH, &BNDH[1], ERRH, 1, (dvoid *) rset, 0, SQLT_RSET, (dvoid *) &(inds[1]), &(rlens[1]), &(rcode[1]), 0, (ub4 *) 0, OCI_DEFAULT); /* Execute statement to get next result set*/ OCIStmtExecute(SVCH, STMH, ERRH, 1, 0, (CONST OCISnapshot *) 0, (OCISnapshot *) 0, OCI_DEFAULT); /* Convert next result set to statement handle */ OCIResultSetToStmt(rset, ERRH); rstmt = (OCIStmt *) rset; /* Now rstmt will point to the second result set returned by the remote stored procedure */ /* Repeat execution of get_next_result_set to get the output arguments */
Parent topic: Result Sets and Stored Procedures
4.3.3.2 PL/SQL Program Fetching from Result Sets in Sequential Mode
This example shows a PL/SQL program fetching from result sets in sequential mode.
Assume that the table LOC_EMP
is a local table exactly like the UDB EMP
table. The same assumption applies that the LOC_DEPT
. OUTARGS
is a table with columns corresponding to the out arguments of the SQL Server stored procedure.
create or replace package rcpackage is type RCTYPE is ref cursor;end rcpackage;/ declare rc1 rcpackage.rctype; rec1 loc_emp%rowtype; rc2 rcpackage.rctype; rec2 loc_dept%rowtype; rc3 rcpackage.rctype; rec3 outargs%rowtype; out_arg varchar2(255); begin -- Execute procedure out_arg := null; refcurproc@UDB('Hello World', out_arg, rc1); -- Fetch 20 rows from the remote emp table and insert them into loc_emp for i in 1 .. 20 loop fetch rc1 into rec1; insert into loc_emp (rec1.empno, rec1.ename, rec1.job, rec1.mgr, rec1.hiredate, rec1.sal, rec1.comm, rec1.deptno); end loop; -- Close ref cursor close rc1; -- Get the next result set returned by the stored procedure rc2 := dbms_hs_result_set.get_next_result_set@UDB; -- Fetch 5 rows from the remote dept table and insert them into loc_dept for i in 1 .. 5 loop fetch rc2 into rec2; insert into loc_dept values (rec2.deptno, rec2.dname, rec2.loc); end loop; --Close ref cursor close rc2; -- Get the output arguments from the remote stored procedure -- Since we are in sequential mode, they will be returned in the -- form of a result set rc3 := dbms_hs_result_set.get_next_result_set@UDB; -- Fetch them and insert them into the outarguments table fetch rc3 into rec3; insert into outargs (rec3.outarg, rec3.retval); -- Close ref cursor close rc3; end; /
Parent topic: Result Sets and Stored Procedures