Previous PageTop Of PageTable Of ContentsNext Page


11. Stored Procedures

11.1 Creating Stored Procedures

11.2 Executing Stored Procedures

11.3 Dropping A Stored Procedure
11.4 Getting Procedure Information
11.5 Creating A Procedure From Files
11.6 Security


11. Stored Procedures

A stored procedure is a special kind of user-defined function which contains embedded SQL statements. Once the stored procedure is created, it is stored in an executable format in the database as an object of the database. This allows you to bypass repeated SQL compilation and optimization, increasing the performance of frequently repeated tasks. You can execute a stored procedure as a command in interactive SQL, or invoke it in application programs, trigger actions, or other stored procedures.

You can accomplish a wide range of objectives with stored procedures, including improving database performance, simplifying the writing of applications, and limiting or monitoring access to a database.

Because a stored procedure is stored in an executable object in the database, it is available to every application running on the database. Several applications can use the same stored procedure so development time for an application is reduced.

11.1 Creating Stored Procedures

You write an ESQL/C program to create a stored procedure. You can use stored procedures to perform any function a C application can, including calling other C functions and system calls.

An ESQL/C program for a stored procedure consists of a CREATE PROCEDURE statement, a declare section if needed, and the code section.

Example 1

EXEC SQL CREATE PROCEDURE a_phone (CHAR(13) name, CHAR(13) phone OUTPUT)
                RETURNS STATUS;
{
    EXEC SQL BEGIN CODE SECTION;
        EXEC SQL SELECT PHONE FROM TBL WHERE NAME = :name INTO :phone;
        EXEC SQL RETURNS STATUS SQLCODE;
    EXEC SQL END CODE SECTION;
}

Example 1 is a procedure with one input parameter, one output parameter and a return value (status). The structure of this program will be explained in the following sections.

Create Procedure Syntax

In the head of a procedure definition is a CREATE PROCEDURE statement. The syntax of the CREATE PROCEDURE statement is:

<procedure creation> ::= CREATE PROCEDURE <procedure def name>
                                        [ <procedure parameters> ]
                                        [ <procedure return result> ]
<procedure def name> ::= [ <module name> '.'] <procedure name>
<module name> ::= IDENT
<procedure name> ::= IDENT
<procedure parameters> ::= <procedure parameter>
                      [',' <procedure parameters> ]
<procedure parameter> ::= <parameter type>
                          <parameter name>
                        [ <parameter mode> ]
<parameter type> ::= <SQL type>
<parameter name> ::= IDENT
<parameter mode> ::= IN | OUT | INPUT | OUTPUT
<procedure return result> ::= RETURNS STATUS |
                              RETURNS [ STATUS',' ] <procedure results>
<procedure results> ::= <procedure result> [',' <procedure results>]
<procedure result>  ::= <result type> <result name>
<result type> ::= <SQL type>
<result name> ::= IDENT

Examples

CREATE PROCEDURE p1 (INTEGER n IN) RETURNS STATUS;


CREATE PROCEDURE m1.p2 (INTEGER n1 IN, INTEGER n2 OUT)
         RETURNS CHAR(12) nm;


CREATE PROCEDURE m1.p3 (CHAR(10) par1 OUT, SMALLINT par1)
         RETURNS STATUS, TIMESTAMP ret1, FLOAT ret2;

In a create procedure statement the procedure name must be provided. The module name in front of the procedure name is optional. The module name will be explained later.

Using Parameters

If parameters are needed, a list of type-name pairs for the parameters must be given in parentheses. IN/OUT (or INPUT/OUTPUT) parameter attributes must be put after each type-name pair. If there is no parameter attribute followed, IN is used by default. Input parameters are used to pass a value to a procedure. As in example 1, it has one input parameter, name. Whenever you execute the procedure, you need to provide a value for the input parameter.

Output parameters are used to get a single result (not a result set) after the procedure is executed. As in example 1, procedure a_phone has an output parameter, phone. You must assign a buffer for the output parameter for receiving the result. After the procedure executes, you can get the phone number of the name you input from the buffer (if any).

A stored procedure may also retrieve a result set of tuples from the database, in this case the result list are needed. If the procedure does not return any selected result then there is no need for result list. The keyword RETURNS is used to start the result list. It is a list of type name pairs (see example below).

Example

EXEC SQL CREATE PROCEDURE t19 (FLOAT ifl) RETURNS STATUS,
                                                  FLOAT fl,
                                                 DOUBLE db;
{
    EXEC SQL BEGIN CODE SECTION;
    EXEC SQL RETURNS STATUS SQLCODE;
    EXEC SQL RETURNS SELECT fl, db FROM t8
                                  WHERE fl < :ifl into :fl, :db;
    EXEC SQL END CODE SECTION;
}

Another keyword STATUS is used to indicate there is a integer value returned after the procedure is executed. This is like the return code of a C int function.

For both input and output parameters, DBMaker now supports the following data types: INTEGER, SMALLINT, SERIAL, CHAR(), DATE, TIME, TIMESTAMP, FLOAT, DOUBLE, REAL.

Return Select Statement

A procedure can return a result set. The result set must use the host variable mechanism to pass out to the caller who execute the stored procedure. We shall explain this later in execution of a stored procedure. However, in the code of stored procedure you need to use the RETURNS keyword to let preprocessor generate host variable related C code. The RETURNS keyword precede the select statement that produces the result set.

Example

EXEC SQL CREATE PROCEDURE  get_all_phone
                  RETURNS CHAR(12) name, CHAR(12) phone;
{
    EXEC SQL BEGIN CODE SECTION;
        EXEC SQL RETURNS SELECT NAME, PHONE FROM TBL INTO :name, :phone;
    EXEC SQL END CODE SECTION;
}

There are two RETURNS in this simple piece of code, one in the create procedure statement and the other in the select statement, which form a pair. That is, if there is a result set returned, you need to declare output parameters with RETURNS in the create procedure statement and put the RETURNS keyword in the select statement. In example 2, the RETURNS keyword is also used to return the status.

Module Names

Users can write several stored procedures in one ESQL source file. The module name is used to tell the database server which module contains the procedures. The default module name is the procedure name.

Code Section

Except for variable declaration, all other statements should be in the code section. Any non-declaration statement before the code section may cause problems (compile errors or wrong results). Statements after the CODE SECTION will not be executed.

11.2 Executing Stored Procedures

You can invoke a stored procedure in dmSQL, in a C program (ODBC or ESQL), in another stored procedure, or in a trigger action.

Execute Stored Procedures in dmSql

The syntax for executing a stored procedure in dmSQL is:

<procedure call> ::=  CALL <procedure calling name>
                  [( <call parameters> )]
<procedure calling name> ::= [<owner name> '.'] <procedure name>
<owner name> ::= IDENT
<call parameters> ::= <call parameter> [ ',' <call parameters> ]
<call parameter>  ::= ':' IDENT 

Examples

dmSQL> CALL p1 (3);

dmSQL> CALL SYSADM.p2 (5, :n2);

dmSQL> CALL SYSADM.p3 (:par1, 7);

If the procedure returns a result set, dmSQL automatically handles the output parameters and displays the result set on the screen. The result set appears on the screen just like you type in a SELECT statement in dmSQL.

dmSql> call a_phone('jeff');

       STATUS        PHONE
       =========================
       0       408-255-2689

dmSql> call sel_all_phone;

       NAME             PHONE
       ============================
       Jerry           02-775-8615
       Jeff            408-255-2689

Executing Stored Procedures in ESQL programs

The syntax for executing a stored procedure in an ESQL program is:

<procedure call> ::= [<status> '=' ] CALL <procedure calling name>
                     [(<call parameters>)] [INTO <return parameters>]
<status> ::= ':' IDENT
<procedure calling name> ::= [<owner name> '.'] <procedure name>
<owner name> ::= IDENT
<call parameters> ::= <call parameter> [ ',' <call parameters> ]
<call parameter>  ::= ':' IDENT

Examples

EXEC SQL :s = CALL p1 (3);


EXEC SQL CALL SYSADM.p2 (5, :n2) INTO :nm;


EXEC SQL :s = CALL jack.p3 (:par1, 7) INTO :ret1, :ret2;

The syntax used in an ESQL program is almost the same as in dmSQL, except the status is automatically received by dmSQL. In ESQL, users must use a host variable to receive the status.

Executing Stored Procedures within a Stored Procedure

Since a stored procedure program is an ESQL/C program, so you can invoke a stored procedure inside a stored procedure exactly the way you would use it in an ESQL/C program. There is only one exception: regular ESQL programs cannot use the RETURNS keyword but the stored procedure can use the RETURNS keyword when invoking another stored procedure.

Assume stored procedure sel_all_phone returns a multiple tuple result set. A regular ESQL program needs to use a cursor to fetch the tuples when invoking this procedure as shown in last section. Within another stored procedure sp2, you can use the same method to fetch tuples and examine the data. But you can also return the whole result set of the called stored procedure to the caller directly from within the current stored procedure. For example you can have this following statement inside stored procedure sp2.

EXEC SQL RETURNS CALL sel_all_phone INTO :oName, :oPhone;

Remember when a stored procedure returns another stored procedure's result set, then the caller must have exactly same result set list, or the same as the first n result columns of the called procedure.

Executing Stored Procedures in ODBC programs

You can also call a stored procedure in an ODBC program. To do this, you have to bind parameters for procedure parameters, and bind columns for procedure to return the result set. In an ODBC program, you can bind partial columns of the result set. After the procedure executes, output parameters are returned in the host variables. You must fetch like a SELECT command to get the result set.

Procedure declaration:

CREATE PROCEDURE proc1(CHAR(12) p1, CHAR(12) p2 OUTPUT)
         RETURNS INTEGER i;

Example ODBC program that calls proc1:

SQLPrepare(cmdp,(UCHAR*)"call proc1(?, ?)", SQL_NTS);
strcpy(bpname, "12345");

SQLBindParameter(cmdp, 1, SQL_PARAM_INPUT_OUTPUT, SQL_C_CHAR, SQL_CHAR,
                      20, 0, &p1, 20, NULL);

SQLBindParameter(cmdp, 2, SQL_PARAM_INPUT_OUTPUT, SQL_C_CHAR, SQL_CHAR,
                      20, 0, &p2, 20, NULL);

SQLBindCol(cmdp, 1, SQL_C_LONG, &i, sizeof(long), NULL);

SQLExecute(cmdp);                                 /* get p2           */

while ((rc=SQLFetch(cmdp))!=SQL_NO_DATA_FOUND)    /* fetch result set */

11.3 Dropping A Stored Procedure

The syntax of the DROP PROCEDURE statement is:

<drop procedure> ::= DROP PROCEDURE <procedure def name>

<procedure def name> ::= [ <module name> '.'] <procedure name>

<module name> ::= IDENT

<procedure name> ::= IDENT

Examples

DROP PROCEDURE proc1;


DROP PROCEDURE m1.proc2;

11.4 Getting Procedure Information

Users using dmSQL can view two system views to get information of procedure: SYSPROCINFO and SYSPROCPARAM.

SELECT * FROM SYSPROCINFO;


SELECT * FROM SYSPROCPARAM;

ODBC functions SQLProcedure() and SQLProcedureColumns() are used to get procedure and parameter information in programs.

11.5 Creating A Procedure From Files

Users can create procedures from files which contain procedure source. The syntax is:

<create proc from file> ::= CREATE PROCEDURE FROM <file path name>

<file path name> ::= <string>

Examples

CREATE PROCEDURE FROM 'proc1.ec';


CREATE PROCEDURE FROM '../esql/proc2.ec';


CREATE PROCEDURE FROM '/usr1/paxtsai/sp/esql/proc3.ec';

<file path name> can be a relative or absolute path. The file must be an ESQL source. The client will translate the contents of the file to the server, and the server will automatically call the preprocessor to generate the C code and call the C compiler and linker to generate target file.

11.6 Security

A stored procedure can be executed by DBAs and its owner. Other users can execute the procedure when the execution privilege is granted to them or PUBLIC.

The GRANT/REVOKE syntax is:

GRANT EXECUTE ON PROCEDURE <procedure name> TO <auth user list>;

REVOKE EXECUTE ON PROCEDURE <procedure> FROM <auth user list>;

Previous PageTop Of PageTable Of ContentsNext Page

Copyright 2002 SYSCOM Computer Engineering Co. All rights reserved.