RE: [PHP-DB] OCI8 support for DBMS_SQL (dynamic sql)
| From: | Fred M. Bulah | Date: | Sat, 01 Jul 2000 21:25:46 +0000 |
| Subject: | RE: [PHP-DB] OCI8 support for DBMS_SQL (dynamic sql) | ||
| References: | 1 | Groups: | php.db |
| Request: | Send a blank email to php-db+get-803@lists.php.net to get a copy of this message | ||
Does the PHP OCI8 interface support calling procedures that use the dynamic
sql package DBMS_SQL? The DBMS_SQL package lets you build dynamic sql. For
queries, you need a cursor which is set up in the following manner:
rec employee%ROWTYPE;
sql_string VARCHAR2(64) := "SELECT employee_id, last_name FROM employee";
c INTEGER := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c, sql_string, DBMS_SQL.V7);
DBMS_SQL.DEFINE_COLUMN(c, 1, rec.employee_id);
DBMS_SQL.DEFINE_COLUMN(c, 2, rec.last_name);
DBMS_SQL.EXECUTE(c);
This takes you to the point where you can retrieve data by calling
DBMS_SQL.FETCH_ROWS().
However, if the idea is to allow the application to read the data in a
manner similar to the way that it would with a REF CURSOR, the procedure
should return this dynamic sql cursor to the application at this point and
let it take over.
The motivation for this is the following scenario:
I need to have a stored procedure order the returned results of a query on
one of 4 different fields either in ascending or descending order. Writing
a separate static procedure in the containing package for each case is error
prone, wasteful, and not flexible. Nor do I want the application to have
any embedded SQL (the package is the API to the database, and shields it
from schema changes and the like).
I thought of having 1 procedure do the setup that includes the above code,
and a separate procedure that does the fetching (closing the cursor when
done). I guess this would work, although I haven't tried it yet. The
problem is that it requires that the application know that the stored
procedure executes dynamic sql and therefore use an entirely different
method for retrieving data (a call to OCIExecute() to the 1st proc to set up
the cursor and execute it, followed by repeated calls to the 2nd proc via
OCIExecute() until no more data is available) from the method used to
execute a stored procedure that does not execute dynamic sql and returns a
REF CURSOR.
This is not very clean since it means that any time you want change an
existing procedure to use dynamic sql, you not only have to change the
procedure but the application as well. The use of dynamic sql should be
transparent to the application.
Thoughts/comments/suggestions?