You are on page 1of 31

1.

Using Client-Side Dynamic SQL


The EXEC_SQL Package

This document describes the client-side dynamic SQL package, EXEC_SQL. The following
topics are described:
• the differences between the EXEC_SQL package and the DBMS_SQL package.
• the differences between the EXEC_SQL package and the Oracle Call Interface.
• using the EXEC_SQL package to execute DDL
• using the EXEC_SQL package against several data sources simultaneously
7DEOH2I&RQWHQWV

TABLE OF CONTENTS ..............................................................................................................................2

OVERVIEW ..................................................................................................................................................4
ACCESSING THE EXEC_SQL PACKAGE .......................................................................................................5
IMPORTANT NOTE FOR DEVELOPER/2000 RELEASE 1.X USERS .....................................................................5
EXEC_SQL COMPARED TO DBMS_SQL AND THE OCI ...................................................................6
USING EXEC_SQL AGAINST NON-ORACLE DATA SOURCES ........................................................................6
EXECUTION FLOW....................................................................................................................................7

PROCEDURES AND FUNCTIONS..........................................................................................................10


IMPORTANT NOTES ON EXEC_SQL FUNCTIONS AND PROCEDURES ..........................................................11
PROCESSING RESULT SETS FROM QUERIES OR NON-ORACLE STORED PROCEDURES ...................................11
OPEN_CONNECTION F UNCTION ...........................................................................................................12
CURR_CONNECTION FUNCTION ...........................................................................................................12
OPEN_CURSOR FUNCTION .....................................................................................................................13
PARSE PROCEDURE ..................................................................................................................................13
DESCRIBE_COLUMN PROCEDURE ........................................................................................................14
BIND_VARIABLE PROCEDURES .............................................................................................................14
DEFINE_COLUMN PROCEDURE .............................................................................................................16
EXECUTE FUNCTION ...............................................................................................................................16
EXECUTE_AND_FETCH F UNCTION ......................................................................................................17
FETCH_ROWS FUNCTION........................................................................................................................17
MORE_RESULT_SETS F UNCTION ..........................................................................................................18
COLUMN_VALUE PROCEDURES ............................................................................................................18
VARIABLE_VALUE PROCEDURE ...........................................................................................................19
IS_OPEN FUNCTION..................................................................................................................................20
CLOSE_CURSOR PROCEDURE ................................................................................................................20
IS_CONNECTED FUNCTION ....................................................................................................................21
IS_OCA_CONNECTION FUNCTION ........................................................................................................21
CLOSE_CONNECTION PROCEDURE ......................................................................................................21
STATUS RETRIEVING FUNCTIONS.....................................................................................................22
LAST_ERROR_POSITION F UNCTION ....................................................................................................22
LAST_ROW_COUNT FUNCTION.............................................................................................................23
LAST_SQL_FUNCTION_CODE FUNCTION ...........................................................................................23
LAST_ERROR_CODE FUNCTION............................................................................................................23
LAST_ERROR_MESG FUNCTION............................................................................................................24
NOTES ON DEFAULTING CONNECTION HANDLES.......................................................................24

EXAMPLES.................................................................................................................................................26
EXAMPLE 1: EXECUTING ARBITRARY SQL AGAINST ANY CONNECTION.....................................................26
EXAMPLE 2: COPYING DATA BETWEEN TWO DATABASES...........................................................................27
EXAMPLE 3: EXECUTING A NON-ORACLE DATABASE STORED PROCEDURE AND FETCHING ITS RESULT SET29


GENERAL LIMITATIONS .......................................................................................................................31


2YHUYLHZ

EXEC_SQL allows you to use dynamic SQL within your PL/SQL code. Dynamic
SQL statements are not embedded in your source program; rather, they are stored in
character strings that are input to, or built by, the program at runtime.
This permits you to write code that is more general purpose. For example, you can
create a procedure that operates on a table whose name is not known until runtime.
Additionally, you can issue any data manipulation language (DML) or data definition
language (DDL) statement using the EXEC_SQL package. This helps solve the
problem of not being able to use data definition language statements directly in
PL/SQL. For example, you might now choose to issue a DROP TABLE statement
from within a PL/SQL procedure by using the PARSE and EXECUTE procedures
supplied with the EXEC_SQL package.
You can also use EXEC_SQL to issue anonymous blocks of PL/SQL to the database,
or to issue calls to non-Oracle stored procedures (using ODBC syntax, as in Example
3 at the end of this document).
The EXEC_SQL package is connection based, and allows users to execute dynamic
SQL against several different databases on several different connections at the same
time. Connections may either be native Oracle connections or connections to ODBC
data sources via the Open Client Adapter (OCA), which is supplied with
Developer/2000.
If you want to access multiple databases, you open a connection for each database, and
receive a ’handle’ by which you can reference that connection. Then on all subsequent
calls to EXEC_SQL routines, you include this handle, and the SQL is executed against
that connection. If you only want to access the current database (that is, the
connection established by Developer/2000), you do not ever have to use a connection
handle - all the EXEC_SQL calls are overloaded to default to the current connection if
no connection handle is supplied.
The EXEC_SQL package is especially useful when you have to:
• retrieve a result set (or multiple result sets) from a non-Oracle stored
procedure.
• open multiple connections to different Oracle or OCA data sources and
retrieve information from all connections in the same form or report!


$FFHVVLQJWKH(;(&B64/SDFNDJH
The EXEC_SQL package is designed for use with the Developer/2000 products, and
will only work with PL/SQL written for those programs.
To use the EXEC_SQL package, you must attach the library “EXEC_SQL.PLL” to
your form, report or graphics display.
In a future release of Developer/2000, the EXEC_SQL package will be a built-in
package, and you will not need to attach the EXEC_SQL.PLL library.
A sample usage of the EXEC_SQL package can be seen in the demo form
MULTCONN.FMB (provided with the EXEC_SQL installation in Developer/2000
release 1.X) or in the Developer/2000 release 2.0 standard “Benefits and Features”
demos.
,PSRUWDQWQRWHIRU'HYHORSHUUHOHDVH[XVHUV
In Developer/2000 Release 1.x, there is no mechanism for getting a handle to the
current Developer/2000 connection when it is a native Oracle connection. Therefore,
CURR_CONNECTION will not return a valid handle against Oracle connections, and
functions that you call without passing a connection handle will not work either. This
means that in Developer/2000 release 1.x, EXEC_SQL may only be used against the
current Developer/2000 connection (as opposed to creating a new connection) if it is
an OCA (ODBC) connection.
The only way of executing dynamic SQL against Oracle is to create and use a new
connection (using OPEN_CONNECTION).
There is no such limitation in Developer/2000 Release 2.0 and above.


(;(&B64/FRPSDUHGWR
'%06B64/DQGWKH2&,

The EXEC_SQL interface is based on the Oracle DBMS_SQL package, although it


offers some extra functionality, such as multiple database connections and describe
result columns. DBMS_SQL is in turn based on the Oracle Call Interface (OCI). So
the section on DBMS_SQL in the Oracle7 Server Application Developer’s Guide, and
the Programmer’s Guide to the Oracle Call Interface, give additional information on
the concepts presented in this document.
When making calls on the current connection, when the connection handle need not be
supplied, the EXEC_SQL interface is very similar to the DBMS_SQL interface.
The interface should also be familiar to Oracle OCI programmers, although there are
some differences because, for example, addresses (also called pointers) are not visible
to users in PL/SQL. These differences include:
• The OCI uses bind by address, while the EXEC_SQL package uses bind
by value.
• With EXEC_SQL you must call VARIABLE_VALUE to retrieve the
value of an OUT bind parameter and you must call COLUMN_VALUE
after fetching rows to actually retrieve the values in the result set.
• The current release of the EXEC_SQL package does not provide support
for CHAR, RAW, LONG or ROWID data.
• The current release of the EXEC_SQL package does not provide a
CANCEL cursor procedure, nor support for the array interface.
• Indicator variables are not required because nulls are fully supported as
values of a PL/SQL variable.

8VLQJ(;(&B64/DJDLQVWQRQ2UDFOH'DWD6RXUFHV
The EXEC_SQL package can be used to access non-Oracle Data Sources by using the
Oracle Open Client Adapter (OCA), which is supplied with Developer/2000. You
must have the OCA installed in order to be able to access non-Oracle data sources, as
well as an appropriate ODBC driver. Please refer to the OCA documentation for more
information.


([HFXWLRQ)ORZ

EXEC_SQL functions and procedures are usually called in the order of the descriptions
below. Note that OPEN_CONNECTION, CURR_CONNECTION and
CLOSE_CONNECTION are optional if you only want to execute SQL against the current
(Developer/2000) connection.

OPEN_CONNECTION
OPEN_CONNECTION opens a new connection to a database, and returns a handle
representing this connection. This handle (of type EXEC_SQL.ConnType) will be
used in subsequent calls to EXEC_SQL routines, to let EXEC_SQL know which
database connection you want to interact with.

CURR_CONNECTION
The CURR_CONNECTION function will return a connection handle for the current
connection (as established by Developer/2000). If you use the
CURR_CONNECTION function, then you must call CLOSE_CONNECTION for
this handle when it is no longer required, as you would for a handle returned by
OPEN_CONNECTION.

OPEN_CURSOR
To process a SQL statement, you must have an open cursor. When you call the
OPEN_CURSOR function, you receive a cursor ID handle (defined as type
EXEC_SQL.CursType) for the data structure representing a valid cursor maintained
by the database you are connected to. These cursor handles are separate from the
cursors defined at the precompiler, OCI or PL/SQL level, and are used only by the
EXEC_SQL package.

PARSE
Every SQL statement must be parsed by calling the PARSE procedure. Parsing the
statement checks the statement’s syntax and associates it with the cursor in your
program.
You can parse any data manipulation language or data definition language statements.
For Oracle, DDL statements are executed on the parse, which performs the implied
commit. For non-Oracle data-sources, the DDL may be executed on the parse or on
the execute. For this reason, we recommend you always PARSE and EXECUTE all
DDL statements.

DESCRIBE_COLUMN
After you parse a SELECT statement, you can use DESCRIBE_COLUMN to obtain
information about the columns in the result set.


BIND_VARIABLE
Many data manipulation language statements require that data in your program be
input to Oracle. When you define a SQL statement that contains input data to be
supplied at runtime, you must use placeholders in the SQL statement to mark where
data must be supplied. You must also use placeholders for output values if the
statement is a PL/SQL block or a call to a stored procedure with output parameters.
For each input placeholder in the statement, you must call the BIND_VARIABLE
procedure to supply the value of a variable in your program to the placeholder. When
the SQL statement is subsequently executed, Oracle uses that value for the
placeholder. You must also call BIND_VARIABLE for each output placeholder.
This tells EXEC_SQL which type of variable you will use to retrieve the output value
in a subsequent VARIABLE_VALUE call.

DEFINE_COLUMN
The columns of the rows being selected in a SELECT statement, or returned by a non-
Oracle stored procedure, are identified by their relative positions as they appear in the
result set, from left to right. For a query, you must call DEFINE_COLUMN for any
column you will later retrieve data for (using COLUMN_VALUE).

EXECUTE
Call the EXECUTE function to execute your SQL statement.

FETCH_ROWS
Call FETCH_ROWS to retrieve the rows that satisfy the query. Each call to
FETCH_ROWS retrieves another row, until there are no more rows. It is possible to
combine EXECUTE and the first call to FETCH_ROWS in a single call to
EXECUTE_AND_FETCH. This can be useful to reduce network traffic, or to
simplify your code when only one row is to be fetched

VARIABLE_VALUE / COLUMN_VALUE
For queries, call COLUMN_VALUE to determine the value of a column retrieved by
the FETCH_ROWS call. For statements containing anonymous PL/SQL blocks or
calls to stored procedures, call VARIABLE_VALUE to retrieve the values assigned to
output variables after the EXECUTE call.

CLOSE_CURSOR
When you no longer need a cursor for a session, close the cursor by calling
CLOSE_CURSOR. This is important because if you neglect to close a cursor, the
memory used by that cursor remains allocated even though it is no longer needed1.

1
Actually, this is not quite true. Any cursor OPENed against a connection handle obtained using
OPEN_CONNECTION or CURR_CONNECTION will be automatically closed when you call
CLOSE_CONNECTION.


CLOSE_CONNECTION
When you no longer need a connection handle (as returned by
OPEN_CONNECTION or CURR_CONNECTION), you must close the connection
using CLOSE_CONNECTION. This is important because otherwise the memory
used for that connection (including un-closed cursors) remains allocated, and the
underlying database connection remains open, which may result in deadlocks with
other connections, or in other users having their connections refused.


3URFHGXUHVDQG)XQFWLRQV

Function/Procedure Description Refer to


Page
OPEN_CONNECTION Establishes a new connection and returns a 11
connection handle for it.
CURR_CONNECTION Returns the connection handle of the current 12
(primary) connection being used by the
Developer/2000 application.
OPEN_CURSOR Creates a new cursor and returns a cursor 13
handle for it.
PARSE Parses a given statement. 13
DESCRIBE_COLUMN Describes the result set. 14
BIND_VARIABLE Binds a given value to a given variable. 14
DEFINE_COLUMN Defines a column to be fetched from the 15
given cursor (used only with SELECT
statements, or calls to non-Oracle stored
procedures that return result sets)
EXECUTE Executes a given cursor 16
EXECUTE_AND_FETCH Executes a given cursor and fetches a row. 17
FETCH_ROWS Fetches a row from a given cursor. 17
MORE_RESULT_SETS Returns TRUE if another result set is 18
available on a cursor, and initializes that
result set
COLUMN_VALUE Returns value of column at given position 18
for most recently fetched row in result set
VARIABLE_VALUE Returns value of named variable for a given 19
cursor.
IS_OPEN Returns TRUE if given cursor is open. 20
CLOSE_CURSOR Closes given cursor and frees memory. 20
IS_CONNECTED Returns TRUE if given connection handle is 21
currently connected to a data source.


IS_OCA_CONNECTION Returns TRUE if given connection handle is 21
for an OCA (ODBC) connection.
CLOSE_CONNECTION Close the given connection handle. 21
LAST_ERROR_POSITION Return byte offset in the SQL statement text 22
where an error occurred.
LAST_ROW_COUNT Returns cumulative count of rows fetched. 23
LAST_SQL_RETURN_CODE Returns SQL function code for statement 23
(see OCI documentation for definition of
SQL function codes)
LAST_ERROR_CODE Returns last error code raised on given 23
connection.
LAST_ERROR_MESG Returns the last error message for given 24
connection
Table 1 EXEC_SQL Package Functions and Procedures

,PSRUWDQW1RWHVRQ(;(&B64/)XQFWLRQVDQG3URFHGXUHV
Connection handles passed to EXEC_SQL routines must be valid, with the exception
of CLOSE_CONNECTION (which will do nothing for an invalid connection). You
can check the validity of a connection handle by checking if your handle is null.
If you pass a null connection handle to an EXEC_SQL function (except for
CLOSE_CONNECTION), or if you don’t pass a connection handle and your
Developer/2000 application is not currently connected to a database, the exception
EXEC_SQL.INVALID_CONNECTION will be raised.
Unless otherwise documented in a function or procedure description, the only other
exception returned is EXEC_SQL.PACKAGE_ERROR. This is returned for any
general error, and the programmer can find out what error has occurred by calling
EXEC_SQL.LAST_ERROR_CODE and EXEC_SQL.LAST_ERROR_MESG.

3URFHVVLQJUHVXOWVHWVIURP4XHULHVRUQRQ2UDFOH6WRUHG3URFHGXUHV
In order to process a statement that returns a result set, you must perform the following
steps:
1. Specify the variables that are to receive the values fetched by calling
DEFINE_COLUMN for each column which you wish to retrieve later
using COLUMN_VALUE.
2. Execute the statement by calling EXECUTE
3. Call FETCH_ROWS to retrieve a row in the result set.
4. Call COLUMN_VALUE to obtain the value of each column retrieved by
FETCH_ROWS.


5. Repeat 3 and 4 until there are no more rows (i.e. FETCH_ROWS returns
0).

Please note that in the descriptions which follow, square brackets [ ] denote optional
parameters.

23(1B&211(&7,21)XQFWLRQ
Call OPEN_CONNECTION to open a new connection to a data source. When you
no longer need this connection, you must close it explicitly using
CLOSE_CONNECTION.
Syntax
The OPEN_CONNECTION function returns the ID handle of the new connection.
The connection string is in the form ‘USER[/PASSWORD][@database_string]’.
Alternatively, you may specify username, password and database_string as separate
arguments to the function. The “database_string” is either a SQLNet alias or an OCA
connection (starting “ODBC:”). The syntax for this function is:
FUNCTION OPEN_CONNECTION ( Connstr IN VARCHAR2 )
RETURN ConnType;
FUNCTION OPEN_CONNECTION (
Username IN VARCHAR2,
Password IN VARCHAR2,
Data source IN VARCHAR2 ) RETURN ConnType;

&855B&211(&7,21)XQFWLRQ
Call CURR_CONNECTION to get a handle to the primary connection being used by
a Developer/2000 application. This can be useful if you have code which takes a
connection handle as a parameter and which works indifferently against either the
current Developer/2000 connection or against additional connections established using
OPEN_CONNECTION.
When you no longer need the handle to the current connection, you should call
CLOSE_CONNECTION on the handle. This allows EXEC_SQL to free any memory
or resources it has allocated for the connection. EXEC_SQL will not actually close
the connection to the database in this case, because the Developer/2000 application
must still be able to continue working.
Note: The first time you call CURR_CONNECTION, EXEC_SQL will find the
current connection being used by your Developer/2000 application, cache it, and
return a handle to you. Each time after you call CURR_CONNECTION, the cached
connection handle will be returned, that is, EXEC_SQL will not ask Developer/2000
for its current connection every time.
Consequently, if you change your primary connection after you've called
CURR_CONNECTION (e.g. by using the Forms built-ins logout and logon), the next


call to CURR_CONNECTION will not automatically return a handle to the new
connection. You must first call CLOSE_CONNECTION on the handle you received
from CURR_CONNECTION.
Syntax
The CURR_CONNECTION function returns a connection handle for the current
Developer/2000 connection. The syntax for this function is:
FUNCTION CURR_CONNECTION RETURN ConnType;

23(1B&85625)XQFWLRQ
Call OPEN_CURSOR to open a new cursor on a specified connection. If you do not
specify a connection, CURR_CONNECTION will be used. When you no longer need
this cursor, you must close it explicitly by calling CLOSE_CURSOR.
You can use cursors to execute the same SQL statement repeatedly (without reparsing)
or to execute a new SQL statement (which must be parsed). When a cursor is reused
for a new statement, the contents of the corresponding cursor data area are reset when
the new statement is parsed. It is never necessary to close and reopen a cursor before
reusing it.
Syntax
The OPEN_CURSOR function returns the cursor ID handle of the new cursor. The
syntax for this function is:
FUNCTION OPEN_CURSOR [(Connid IN ConnType )] RETURN CursType;

3$56(3URFHGXUH
Call PARSE to parse the given statement in the given cursor. Currently, unlike the
OCI OPARSE call, which supports deferred parsing, all statements are parsed
immediately.
Syntax
The parameters of the PARSE procedure are described in Table 2. The syntax for this
procedure is:
PROCEDURE PARSE (
[ Connid IN ConnType, ]
Curs_Id IN CursType,
Statement IN VARCHAR2
[,Language IN PLS_INTEGER]);

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Curs_ID Specify the ID handle of the cursor in which to parse the statement.
Statement Provide the SQL statement to be parsed. Your SQL statement should not
include a final semicolon.
Language_flag This parameter determines how Oracle handles the SQL statement. The
following values are recognized for this parameter:
V6 - Specifies Oracle V6 behavior


V7 - Specifies Oracle V7 behavior
Table 2 EXEC_SQL.PARSE Procedure Parameters

'(6&5,%(B&2/8013URFHGXUH
Call DESCRIBE column to get information about the result set of a parsed SQL
statement. If you attempt to describe a column number that does not exist in the result
set, the exception EXEC_SQL.INVALID_COLUMN_NUMBER is raised. So you
may loop through the columns from 1 until this exception is raised in order to find out
how many columns there are.
Syntax
The parameters of DESCRIBE_COLUMN are described in Table 3. The syntax is:
PROCEDURE DESCRIBE_COLUMN (
[ Connid IN ConnType, ]
Curs_Id IN CursType,
Position IN PLS_INTEGER,
Name IN OUT VARCHAR2,
Collen IN OUT PLS_INTEGER,
Type IN OUT PLS_INTEGER );

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Curs_ID Specify the ID handle of the cursor in which to describe the column.
Position The position in the result set (left to right, first column being 1) of the column you
want to describe
Name On output, this will contain the name of the column.
Collen On output, this will contain the maximum length (in bytes) of the column.
Type On output, this will contain the type of the column. Valid values are:
EXEC_SQL.VARCHAR2_TYPE
EXEC_SQL.NUMBER_TYPE
EXEC_SQL.FLOAT_TYPE
EXEC_SQL.LONG_TYPE
EXEC_SQL.ROWID_TYPE
EXEC_SQL.DATE_TYPE
EXEC_SQL.RAW_TYPE
EXEC_SQL.LONG_RAW_TYPE
EXEC_SQL.CHAR_TYPE -- ANSI fixed CHAR
EXEC_SQL.MLSLABLE_TYPE – Trusted Oracle only
Table 3 EXEC_SQL.DESCRIBE_COLUMN Procedure Parameters

%,1'B9$5,$%/(3URFHGXUHV
Call BIND_VARIABLE to bind a given value to a given variable in a cursor, based on
the name of the variable in the statement. If the variable is an IN or IN/OUT variable,
the given bind value must be valid for the variable type. If the variable is an OUT
variable, the actual value passed is ignored, but you must still call BIND_VARIABLE
for this variable, if you wish to retrieve it later using VARIABLE_VALUE, in order to
indicate the type of PL/SQL variable you will retrieve it into.


The bind variables of a SQL statement are identified by their names. When binding a
value to a bind variable, the string identifying the bind variable in the statement must
contain a leading colon, as shown in the following example:
SELECT ename FROM emp WHERE SAL > :X;

For this example, the corresponding bind call would look similar to
BIND_VARIABLE(connection_handle, cursor_number, ’:X’, 3500);

Syntax
The parameters for the BIND_VARIABLE procedure are described in Table 4. Notice
that the BIND_VARIABLE procedure is overloaded to accept different data types for
the Value parameter. The syntax is:
PROCEDURE BIND_VARIABLE (
[ Connid IN ConnType, ]
Curs_Id IN CursType,
Name IN VARCHAR2,
Value IN <datatype> );

Where <datatype> can be any one of the following:


NUMBER
DATE
VARCHAR2
The following syntax is also supported for the BIND_VARIABLE procedure:
PROCEDURE BIND_VARIABLE (
[ Connid IN ConnType, ]
Curs_Id IN CursType,
Name IN VARCHAR2,
Value IN VARCHAR2,
Out_Value_Size IN PLS_INTEGER);

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Curs_ID Specify the ID handle of the cursor in which to bind the variable.
Name Provide the name of the variable in the statement.
Value Provide the value that you want to bind to the variable in the cursor. For
IN and IN/OUT variables, the value has the same type as the type of the
value being passed in for this parameter. For OUT parameters, the value
has the same type as the type expected to be retrieved for this value.
Out_Value_Size The maximum expected OUT value size, in bytes, for the VARCHAR2
OUT or IN/OUT variable. If no size is given, the current length of the
Value parameter is used.
1. Table 4 EXEC_SQL.BIND_VARIABLE Procedure Parameters


'(),1(B&2/8013URFHGXUH
This procedure is only used with cursors returning result sets. Call
DEFINE_COLUMN to define a column to be selected from the given cursor. The
column being defined is identified by its relative position in the result set of the
statement in the given cursor. The type of the COLUMN parameter determines the
type of the column being defined.

Syntax
The parameters for the DEFINE_COLUMN procedure are described in Table 5.
Notice that this procedure is overloaded to accept different data types. The syntax is :

PROCEDURE DEFINE_COLUMN (
[ Connid IN ConnType, ]
Curs_Id IN CursType,
Position IN PLS_INTEGER,
Column IN < datatype > );

Where <datatype> can be any one of the following types:


NUMBER
DATE
VARCHAR2

The following syntax is also supported for the DEFINE_COLUMN procedure:


PROCEDURE DEFINE_COLUMN (
[ Connid IN ConnType, ]
Curs_Id IN CursType,
Position IN PLS_INTEGER,
Column IN VARCHAR2,
Column_Size IN PLS_INTEGER );

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Curs_Id The ID handle for the row being defined to be selected.
Position The relative position of the column in the row being defined. The first
column in a statement has position 1.
Column The value of the column being defined. The type of this value determines
the type for the column being defined. The actual value stored in the
variable is ignored.
Column_Size The maximum expected size of the column value, in bytes, for columns of
type VARCHAR2
Table 5 EXEC_SQL.DEFINE_COLUMN Procedure Parameters

(;(&87()XQFWLRQ
Call EXECUTE to execute a given cursor. This function accepts the ID handle of the
cursor and returns the number of rows processed. The return value is only valid for


INSERT, UPDATE and DELETE statements; for other types of statements, including
DDL, the return value is undefined and should be ignored.
Syntax
The parameters for the EXECUTE function are described in Table 6. The syntax for
this function is:

FUNCTION EXECUTE (
[ Connid IN ConnType, ]
Curs_Id IN CursType ) RETURN PLS_INTEGER;

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Curs_Id The cursor containing the SQL statement you want to execute.
Table 6 EXEC_SQL.EXECUTE Function Parameters

(;(&87(B$1'B)(7&+)XQFWLRQ
Call EXECUTE_AND_FETCH to execute the given cursor and fetch the first row.
This function provides the same functionality as calling EXECUTE and then calling
FETCH_ROWS. Calling EXECUTE_AND_FETCH instead, however, may cut
down on the number of round-trips when used against a remote database.
Syntax
The EXECUTE_AND_FETCH function returns the number of rows actually fetched
(0 or 1). The parameters of this function are described in Table 7. The syntax is:

FUNCTION EXECUTE_AND_FETCH (
[ Connid IN ConnType, ]
Curs_Id IN CursType,
Exact IN BOOLEAN DEFAULT FALSE ) RETURN PLS_INTEGER;

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Curs_Id The handle containing the SQL statement you want to execute.
Exact Set to TRUE to raise the exception EXEC_SQL.PACKAGE_ERROR (you
can use LAST_ERROR_CODE and LAST_ERROR_MESG to figure out
what went wrong with the query) if the number of rows actually matching
the query differs from one. Even if an exception is raised, the rows are still
fetched and available.
Table 7 EXEC_SQL.EXECUTE_AND_FETCH Function Parameters

)(7&+B52:6)XQFWLRQ
Call FETCH_ROWS to fetch a row from a given cursor. You can call
FETCH_ROWS repeatedly as long as there are rows remaining to be fetched. The
rows are retrieved into buffers maintained by EXEC_SQL, and must be read by
calling COLUMN_VALUE, for each column, after each call to FETCH_ROWS.


Syntax
The FETCH_ROWS function returns the number of rows actually fetched. If there is
no more data to be fetched in this result set, it returns 0. For non-Oracle data sources,
this does not always mean that there is no more data available on the cursor. See the
MORE_RESULT_SETS function for more information.
The parameters for this function are described in Table 8. The syntax is:

FUNCTION FETCH_ROWS (
[ Connid IN ConnType, ]
Curs_Id IN CursType ) RETURN PLS_INTEGER;

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Curs_Id The cursor containing the statement you want to fetch from.
Table 8 EXEC_SQL.FETCH Function Parameters

025(B5(68/7B6(76)XQFWLRQ
Call MORE_RESULT_SETS to determine if a cursor has more result sets waiting to
be retrieved. This function only applies to non-Oracle stored procedures2.
Syntax
If a stored procedure has another result waiting to be retrieved,
MORE_RESULT_SETS will initialize the cursor to return that result set and return
TRUE. You will have to re-DESCRIBE_COLUMN to see the format of the new
result set, if unknown. Otherwise, if there are no more result sets, it will return
FALSE.
The parameters for this function are described in Table 9. The syntax is:

FUNCTION MORE_RESULT_SETS (
[ Connid IN ConnType, ]
Curs_Id IN CursType ) RETURN BOOLEAN;

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Curs_Id The cursor containing the SQL statement you want to fetch from.
Table 9 EXEC_SQL.MORE_RESULT_SETS Function Parameters

&2/801B9$/8(3URFHGXUHV
This procedure returns the value of a given column in the result set in the row which
was fetched by the last call to FETCH_ROWS on the given cursor.
Syntax

2
Against Oracle, it will always return FALSE


The parameters for the COLUMN_VALUE procedure are described in Table 10. The
syntax for this procedure is (square brackets [] indicate optional parameters):

PROCEDURE COLUMN_VALUE (
[ Connid IN ConnType, ]
Curs_Id IN CursType,
Position IN PLS_INTEGER,
Value IN OUT <datatype>
[,Column_Error IN OUT NUMBER ]
[,Actual_Length IN OUT PLS_INTEGER ]);

Where <datatype> can be any one of the following types:


NUMBER
DATE
VARCHAR2

Parameter Mode
Description
Connid INA handle to the connection you wish to use. If no
connection is given, CURR_CONNECTION is used.
Curs_Id IN Specify the ID handle of the cursor from which you are
retrieving values.
Position IN Specify the relative position of the column in the
cursor. The first column in a statement has position 1.
Value IN/OUT Returns the value at the specified column and row the
cursor is currently at.
If you specify a different return value that what you
originally DEFINE_COLUMNed the column as, a
VALUE_ERROR exception will be raised.
Column_Error IN/OUT Returns any error code for the specified column value,
if available3.
Actual_Length IN/OUT Returns the actual length, before any truncation of the
value in the specified column.
Table 10 EXEC_SQL.COLUMN_VALUE Procedure Parameters

9$5,$%/(B9$/8(3URFHGXUH
This procedure returns the value of the named bind variable for a given cursor. It is
also used to return the values of bind variables inside PL/SQL blocks.
Syntax
The parameters for the VARIABLE_VALUE procedures are described in Table 11.
The syntax for this procedure is:

PROCEDURE VARIABLE_VALUE (
Connid IN ConnType,
Curs_Id IN CursType,
Name IN VARCHAR2,
Value IN OUT <datatype> );

3
Column error codes are not available for ODBC data sources.


Where <datatype> can be any one of the following types:
NUMBER
DATE
VARCHAR2

Parameter Mode Description


Connid IN A handle to the connection you wish to use. If no connection is
given, CURR_CONNECTION is used.
Curs_Id IN Specify the ID handle of the cursor from which to get the
values.
Name IN Specify the name of the variable for which you are retrieving
the value.
Value IN OUT Returns the value of the bind variable for the specified position.
If you attempt to retrieve a datatype other than that which you
originally bound the variable as, a VALUE_ERROR exception
will be raised.
1. Table 11 EXEC_SQL.VARIABLE_VALUE Procedure Parameters
,6B23(1)XQFWLRQ
The IS_OPEN function returns TRUE if the given cursor is currently open on the
given connection.
Syntax
The parameters for the IS_OPEN function are described in Table 12. The syntax is:

FUNCTION IS_OPEN(
[ Connid IN ConnType, ]
Curs_Id IN CursType ) RETURN BOOLEAN;

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Curs_Id The cursor ID handle that you want to know is open.
Table 12 EXEC_SQL.IS_OPEN Function Parameters

&/26(B&856253URFHGXUH
Call CLOSE_CURSOR to close a given cursor. CLOSE_CURSOR will free any
memory or resources allocated by EXEC_SQL for that cursor, and close the cursor on
the database.
Syntax
The parameters for the CLOSE_CURSOR procedure are described in Table 13. The
syntax for this procedure is:

PROCEDURE CLOSE_CURSOR (
[ Connid IN ConnType, ]
Curs_Id IN OUT CursType );

Parameter Mode Description


Connid IN A handle to the connection you wish to use. If no connection is


given, CURR_CONNECTION is used.
Curs_ID IN Specify the ID handle of the cursor that you want to close.
OUT The cursor is set to null. After you call CLOSE_CURSOR, the
memory allocated to the cursor is released and you can no
longer fetch (or do anything) from that cursor.
Table 13 EXEC_SQL.CLOSE_CURSOR Procedure Parameters

,6B&211(&7(')XQFWLRQ
The IS_CONNECTED function returns TRUE if the given connection handle is
connected to a data source, FALSE if it is not.
Syntax
The parameter for IS_CONNECTED is described in Table 14. The syntax is:
FUNCTION IS_CONNECTED( Connid IN ConnType ) RETURN BOOLEAN;

Parameter Mode Description


Connid IN A handle to the connection you wish to use. If no connection is
given, CURR_CONNECTION is used.
Table 14 EXEC_SQL.IS_CONNECTED Function Parameter

,6B2&$B&211(&7,21)XQFWLRQ
The IS_OCA_CONNECTION function return TRUE if the given connection handle
is from an OCA connection, and FALSE otherwise.
Syntax
The parameter for IS_OCA_CONNECTION is described Table 15. The syntax is:
FUNCTION IS_OCA_CONNECTION [( Connid IN ConnType)] RETURN BOOLEAN;

Parameter Mode Description


Connid IN A handle to the connection you wish to use. If no connection is
given, CURR_CONNECTION is used.
Table 15 EXEC_SQL.IS_OCA_CONNECTION Function Parameter

&/26(B&211(&7,213URFHGXUH
Call the CLOSE_CONNECTION procedure to disconnect from an opened connection
(with a handle obtained from OPEN_CONNECTION or CURR_CONNECTION).
CLOSE_CONNECTION will close all cursors opened by OPEN_CURSOR on that
connection, free all memory allocated by EXEC_SQL for the connection, and, if the
connection was opened with OPEN_CONNECTION, it will close the database
connection.
If the connection handle was obtained from CURR_CONNECTION,
CLOSE_CONNECTION will not actually close the database connection.
Syntax


The parameter for CLOSE_CONNECTION is described Table 16. The syntax for
this procedure is:

PROCEDURE CLOSE_CONNECTION ( [ Connid IN OUT ConnType ]);

Parameter Mode Description


Connid IN The connection handle that you wish to close. If you do not
specify a connection handle, the currently stashed connection
handle is reset.
OUT The handle is set to NULL. After you call
CLOSE_CONNECTION, all cursors opened by
OPEN_CURSOR but not closed by CLOSE_CURSOR are
closed, and all memory associated with this handle is released.
Table 16 EXEC_SQL.CLOSE_CONNECTION Procedure Parameter

6WDWXV5HWULHYLQJ
)XQFWLRQV

There are additional functions in the EXEC_SQL package for obtaining information
about the last referenced cursor in a given connection. The values returned by these
functions are only meaningful after a SQL statement is executed. In addition, certain
status-retrieving functions are only meaningful after certain EXEC_SQL calls. For
example, you should only call LAST_ERROR_POSITION immediately after a parse.

/$67B(5525B326,7,21)XQFWLRQ
Returns the byte offset in the SQL statement text where the error occurred. The first
character in the SQL statement is at position 0.
Call this function after a PARSE call, before any other EXEC_SQL procedures or
functions are called.
For OCA data sources, we cannot determine the byte offset at which an error occurred,
so this function is meaningless.
Syntax
The parameters for the LAST_ERROR_POSITION function are described in Table
17. The syntax for this function is (square brackets [] denote optional parameters):

FUNCTION LAST_ERROR_POSITION [( Connid IN ConnType )]


RETURN PLS_INTEGER;

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Table 17 EXEC_SQL.LAST_ERROR_POSITION Function Parameter


/$67B52:B&2817)XQFWLRQ
Returns the cumulative count of the number of rows fetched.
Call this function after a FETCH_ROWS or an EXECUTE_AND_FETCH call. If
called after an EXECUTE call, the value returned will be zero.
Syntax
The parameters for the LAST_ROW_COUNT function are described in Table 18.
The syntax for this function is:

FUNCTION LAST_ROW_COUNT [( Connid IN ConnType )]


RETURN PLS_INTEGER;

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Table 18 EXEC_SQL.LAST_ROW_COUNT Function Parameter

/$67B64/B)81&7,21B&2'()XQFWLRQ
Returns the SQL function code for the statement, which indicate what type of
statement it was (e.g. SELECT, UPDATE, CREATE TABLE, etc.). Valid function
codes are listed in the Programmer’s Guide to the Oracle Call Interface.
You should call this function immediately after the SQL statement is executed;
otherwise the value is undefined.
Syntax
The parameters for the LAST_SQL_FUNCTION_CODE function are described in
Table 19. The syntax is:

FUNCTION LAST_SQL_FUNCTION_CODE [( Connid IN ConnType )]


RETURN PLS_INTEGER;

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Table 19 EXEC_SQL.LAST_SQL_FUNCTION_CODE Function Parameter

/$67B(5525B&2'()XQFWLRQ
Returns the last Oracle Error Code generated by EXEC_SQL on a given connection.
Call this function immediately after the EXEC_SQL.PACKAGE_ERROR exception
is raised, to see what caused the problem.
Syntax
The parameters for the LAST_ERROR_CODE function are described in Table 20.
The syntax is:


FUNCTION LAST_ERROR_CODE [( Connid IN ConnType )]
RETURN PLS_INTEGER;

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Table 20 EXEC_SQL.LAST_ERROR_CODE Function Parameter

/$67B(5525B0(6*)XQFWLRQ
Returns the text message of the last error code that was raised on a given connection
handle.
Call this function immediately after the EXEC_SQL.PACKAGE_ERROR exception
is raised, to get the error message text..
Syntax
The parameters for the LAST_ERROR_MESG function are described in Table 21.
The syntax for this function is:

FUNCTION LAST_ERROR_MESG [( Connid IN ConnType )]


RETURN VARCHAR2;

Parameter Description
Connid A handle to the connection you wish to use. If no connection is given,
CURR_CONNECTION is used.
Table 21 EXEC_SQL.LAST_ERROR_MESG Function Parameter

1RWHVRQ'HIDXOWLQJ
&RQQHFWLRQ+DQGOHV

If you do not specify a connection handle for most EXEC_SQL functions and
procedures, the EXEC_SQL package will use the cached current connection handle.
If you never call CURR_CONNECTION, then EXEC_SQL will automatically close
the cached current connection when you close all the cursors you have opened (via
OPEN_CURSOR) on that connection. In this case you do not need to call
CLOSE_CONNECTION since EXEC_SQL will automatically call it when the last
cursor is closed.
If you ever call CURR_CONNECTION or OPEN_CONNECTION, you must
make sure to call CLOSE_CONNECTION when you are finished.
If you change your default Developer/2000 connection (for example, using the LOGIN
built-in in Forms), EXEC_SQL has no way of knowing this has occurred, and will
continue to use the cached current connection value (which will be completely invalid)


until you inform EXEC_SQL to re-query Developer/2000 to get the
CURR_CONNECTION. You can do this by calling CLOSE_CONNECTION with
no arguments.


([DPSOHV

This section provides example procedures that make use of the EXEC_SQL package.
([DPSOH([HFXWLQJDUELWUDU\64/DJDLQVWDQ\FRQQHFWLRQ
This procedure is passed a SQL statement and optionally a connection string of the
form ’user[/password][@data source]’. If a connection string is passed, it executes the
SQL statement against that data source, otherwise it implements it against the current
connection.

PROCEDURE exec ( sql_string IN VARCHAR2,


connection_string IN VARCHAR2 DEFAULT NULL )
IS
connection_id EXEC_SQL.ConnType;
cursor_number EXEC_SQL.CursType;
ret PLS_INTEGER;
BEGIN
-- Open a new connection. If the connection string is
-- empty, assume the user wants to use the current connection
IF connection_string IS NULL THEN
connection_id := EXEC_SQL.CURR_CONNECTION;
ELSE
connection_id := EXEC_SQL.OPEN_CONNECTION(connection_string);
END IF;

-- Open a cursor on the connection for executing our SQL on.


cursor_number := EXEC_SQL.OPEN_CURSOR(connection_id);

-- Parse the SQL statement on the given connection.


EXEC_SQL.PARSE(connection_id, cursor_number, sql_string);

-- And execute it. If the connection was Oracle,


-- any DDL was done at parse time, but if the connection
-- was a non-Oracle data source, this is not guaranteed.
ret := EXEC_SQL.EXECUTE(connection_id, cursor_number);

-- We are now done with the cursor. We can close it.


EXEC_SQL.CLOSE_CURSOR(connection_id, cursor_number);

-- And we are done with the connection. It is


-- possible that the connection id we have is the
-- CURR_CONNECTION. However, CLOSE_CONNECTION is
-- guaranteed not to actually close this connection,
-- but to release all memory allocated by EXEC_SQL
-- for that connection.
EXEC_SQL.CLOSE_CONNECTION(connection_id);
EXCEPTION
WHEN EXEC_SQL.PACKAGE_ERROR THEN
-- This is the general error raised by the EXEC_SQL
-- package, and denotes an unexpected error in one
-- of the calls. We can get information on what the


-- error was as follows:
-- This prints the error number and error message
-- to standard out.
TEXT_IO.PUT_LINE(’ERROR (’ ||
TO_CHAR(EXEC_SQL.LAST_ERROR_CODE(connection_id)) || ’): ’ ||
EXEC_SQL.LAST_ERROR_MESG(connection_id));
IF EXEC_SQL.IS_CONNECTED(connection_id) THEN
IF EXEC_SQL.IS_OPEN(connection_id, cursor_number) THEN
EXEC_SQL.CLOSE_CURSOR(connection_id, cursor_number);
END IF;
EXEC_SQL.CLOSE_CONNECTION(connection_id);
END IF;
END;

([DPSOH&RS\LQJGDWDEHWZHHQWZRGDWDEDVHV
The following example procedure is passed the names of a source and a destination
table, and a connection string for the source and destination tables respectively. It
copies the rows from the source table (on the source connection) to the destination
table (on the destination connection). This sample procedure assumes that both the
source and destination tables have the following columns:
ID of type NUMBER
NAME of type VARCHAR2(30)
BIRTHDATE of type DATE
This procedure does not specifically require the use of dynamic SQL; however, it
illustrates the concepts of this package.
PROCEDURE copy ( source_table IN VARCHAR2,
destination_table IN VARCHAR2,
source_connection IN VARCHAR2 DEFAULT NULL,
destination_connection IN VARCHAR2 DEFAULT NULL )
IS
id NUMBER;
name VARCHAR2(30);
birthdate DATE;
source_connid EXEC_SQL.ConnType;
destination_connid EXEC_SQL.ConnType;
source_cursor EXEC_SQL.CursType;
destination_cursor EXEC_SQL.CursType;
ignore PLS_INTEGER
BEGIN
-- Open the respective connections.
IF source_connection IS NULL THEN
-- If the user does not specify a secondary connection
-- to be opened, we will use the same connection the
-- Developer/2000 application is using.
source_connid := EXEC_SQL.CURR_CONNECTION;
ELSE
source_connid :=
EXEC_SQL.OPEN_CONNECTION(source_connection);
END IF;
IF destination_connection IS NULL THEN
destination_connid := EXEC_SQL.CURR_CONNECTION;
ELSE
destination_connid :=
EXEC_SQL.OPEN_CONNECTION(source_connection);
END IF;
-- Prepare a cursor to select from the source table


source_cursor := EXEC_SQL.OPEN_CURSOR(source_connid);
EXEC_SQL.PARSE(source_connid, source_cursor,
’SELECT id, name, birthdate FROM ’ || source);
EXEC_SQL.DEFINE_COLUMN(source_connid, source_cursor,
1, id);
EXEC_SQL.DEFINE_COLUMN(source_connid, source_cursor,
2, name, 30);
EXEC_SQL.DEFINE_COLUMN(source_connid, source_cursor,
3, birthdate);
ignore := EXEC_SQL.EXECUTE(source_connid, source_cursor);

-- Prepare a cursor to insert into the destination table


destination_cursor :=
EXEC_SQL.OPEN_CURSOR(destination_connid);
EXEC_SQL.PARSE(destination_connid, destination_cursor,
’INSERT INTO ’ || destination ||
’ (id, name, birthdate) VALUES (:id, :name, :birthdate)’);
-- fetch a row from the source table, and insert it into
-- the destination table
LOOP
IF EXEC_SQL.FETCH_ROWS(source_connid, source_cursor) > 0
THEN
-- get column values for the row
EXEC_SQL.COLUMN_VALUE(source_connid, source_cursor,
1, id);
EXEC_SQL.COLUMN_VALUE(source_connid, source_cursor,
2, name);
EXEC_SQL.COLUMN_VALUE(source_connid, source_cursor,
3, birthdate);
-- bind the row into the cursor that inserts
-- into the destination table.
-- You could alter this example to require
-- the use of dynamic SQL by inserting an if
-- condition before the bind.
EXEC_SQL.BIND_VARIABLE(destination_connid,
destination_cursor, ’:id’, id);
EXEC_SQL.BIND_VARIABLE(destination_connid,
destination_cursor, ’:name’, name);
EXEC_SQL.BIND_VARIABLE(destination_connid,
destination_cursor, ’:birthdate’, birthdate);
ignore := EXEC_SQL.EXECUTE(destination_connid,
destination_cursor);
ELSE
-- no more rows to copy
EXIT;
END IF;
END LOOP;

-- Commit the destination cursor


EXEC_SQL.PARSE(destination_connid, destination_cursor,
’commit’);
ignore := EXEC_SQL.EXECUTE(destination_connid,
destination_cursor);

-- And close everything up.


EXEC_SQL.CLOSE_CURSOR(destination_connid, destination_cursor);
EXEC_SQL.CLOSE_CURSOR(source_connid, source_cursor);
EXEC_SQL.CLOSE_CONNECTION(destination_connid);
EXEC_SQL.CLOSE_CONNECTION(source_connid);
EXCEPTION
WHEN EXEC_SQL.PACKAGE_ERROR THEN


-- This is the general error raised by the EXEC_SQL
-- package, and denotes an unexpected error in one
-- of the calls. We can get information on what the
-- error was as follows:

-- This prints the error number and error message to


-- standard out if an error occurred on the destination
-- connection.
IF EXEC_SQL.LAST_ERROR_CODE(source_connid) != 0 THEN
TEXT_IO.PUT_LINE(’ERROR (source: ’ ||
TO_CHAR(EXEC_SQL.LAST_ERROR_CODE(source_connid))
|| ’): ’ ||
EXEC_SQL.LAST_ERROR_MESG(source_connid));
END IF;
-- This prints the error number and error message to
-- standard out if an error occurred on the destination
-- connection.
IF EXEC_SQL.LAST_ERROR_CODE(destination_connid) != 0 THEN
TEXT_IO.PUT_LINE(’ERROR (destination: ’ ||
TO_CHAR(EXEC_SQL.LAST_ERROR_CODE(destination_connid))
|| ’): ’ ||
EXEC_SQL.LAST_ERROR_MESG(destination_connid));
END IF;

-- We also make sure we free all connections and cursors


-- correctly.
IF EXEC_SQL.IS_CONNECTED(destination_connid) THEN
IF EXEC_SQL.IS_OPEN(destination_connid,
destination_cursor) THEN
EXEC_SQL.CLOSE_CURSOR(destination_connid,
destination_cursor);
END IF;
EXEC_SQL.CLOSE_CONNECTION(destination_connid);
END IF;
IF EXEC_SQL.IS_CONNECTED(source_connid) THEN
IF EXEC_SQL.IS_OPEN(source_connid,
source_cursor) THEN
EXEC_SQL.CLOSE_CURSOR(source_connid,
source_cursor);
END IF;
EXEC_SQL.CLOSE_CONNECTION(source_connid);
END IF;
END;

([DPSOH([HFXWLQJDQRQ2UDFOHGDWDEDVHVWRUHGSURFHGXUHDQG
IHWFKLQJLWVUHVXOWVHW
The following example procedure executes a Microsoft SQL Server stored procedure
that returns a result set, and then fetches that result set. The stored procedure is:
create proc example_proc @id integer as
select ename from emp where empno = @id

The PL/SQL procedure example3 will execute the stored procedure on the current
connection (assuming it is a SQL Server connection), and print out all lines returned.


CREATE PROCEDURE example3 ( v_id IN NUMBER) IS
v_ename VARCHAR2(20);
v_cur EXEC_SQL.CursType;
v_rows INTEGER;
BEGIN
-- Note when no connection handle is passed,
-- EXEC_SQL assumes the current connection.
v_cur := EXEC_SQL.OPEN_CURSOR;
-- Note that to call stored procedures against ODBC
-- datasource, ODBC syntax should be used, but parameters
-- should be specified as though they were Oracle parameters.
EXEC_SQL.PARSE(v_cur, ’{ call example_proc ( :v_id ) }’);
EXEC_SQL.BIND_VARIABLE(v_cur, ’:v_id’, v_id);
v_rows := EXEC_SQL.EXECUTE(v_curs);
EXEC_SQL.DEFINE_COLUMN(v_curs, 1, v_ename, 20);
WHILE EXEC_SQL.FETCH_ROWS(v_curs) > 0 LOOP
EXEC_SQL.COLUMN_VALUE(v_curs, 1, v_ename);
TEXT_IO.PUT_LINE(’Ename = ’ || v_ename);
END LOOP;
EXEC_SQL.CLOSE_CURSOR(v_cur);

EXCEPTION
WHEN EXEC_SQL.PACKAGE_ERROR THEN
TEXT_IO.PUT_LINE(’ERROR (’ ||
TO_CHAR(EXEC_SQL.LAST_ERROR_CODE)
|| ’): ’ ||
EXEC_SQL.LAST_ERROR_MESG);
EXEC_SQL.CLOSE_CURSOR(v_cur);
WHEN EXEC_SQL.INVALID_CONNECTION THEN
-- Note INVALID_CONNECTION is risen when there
-- is no default connection.
TEXT_IO.PUT_LINE(’ERROR: Not currently connected
to a database’);
END example3;


*HQHUDO/LPLWDWLRQV

The EXEC_SQL package is not meant as a replacement for static SQL within
PL/SQL. There are several things that EXEC_SQL does not do:
• In Developer/2000 Release 1.3, CURR_CONNECTION will only work
for OCA data sources.
• Input bind variables of type VARCHAR2 can be at most 2000 bytes long.
• A SQL statement can be at most 2000 bytes long.
• There is no CANCEL_CURSOR procedure or function.
• It will not toast rye bread, so don’t even ask!
• There is no support for array input of variables nor of array fetch.
• There is no support for PL/SQL tables or records types.
• There is no support for CHAR, RAW or ROWID data, or for LONG data
types.



You might also like