Reputation: 13908
I need to know how to obtain the statement type of a prepared statement handle in OCI.
The dilemna is as follows. The fourth argument of OCIStmtExecute()
- iters
- cannot be 0
if the statement is not a SELECT
, but it must be 0
if the statement is a SELECT
(and defines cannot be done ahead of time). From the OCI 10g documentation for OCIStmtExecute
:
For non-SELECT statements, the number of times this statement is executed is equal to iters - rowoff.
For SELECT statements, if iters is nonzero, then defines must have been done for the statement handle. The execution fetches iters rows into these predefined buffers and prefetches more rows depending upon the prefetch row count. If you do not know how many rows the SELECT statement will retrieve, set iters to zero.
This function returns an error if iters=0 for non-SELECT statements.
For a statement such as SELECT * ...
, it is impossible to know what the columns even are before obtaining the describe
information from the statement handle, which is only available after OCIStmtExecute()
is called. (So, it's not possible to do defines
on the statement handle ahead of time.) Therefore, I must pass 0
for iters
if the (unknown) statement type is SELECT
. But if the (unknown) statement type is not SELECT
, OCI returns an error if iters
is 0
(just as the documentation says).
The documented way to obtain the type of statement (SELECT
or not) is by querying an attribute of the statement handle, as follows:
ub2 statementType = 0;
OCIAttrGet(mystmt, OCI_HTYPE_STMT, (dvoid*)(&statementType), NULL, OCI_ATTR_SQLFNCODE, myerrhp);
Unfortunately, this function always returns 0
for statementType
until after OCIStmtExecute()
is called.
I am in a catch-22 situation. I must call OCIAttrGet()
before I call OCIStmtExecute()
to obtain the type of statement in order to set iters
properly. However, I must call OCIStmtExecute()
before OCIAttrGet()
will succeed.
I have tried calling OCIStmtExecute()
twice, the first time passing OCI_DESCRIBE_ONLY
for the final parameter (mode
). Unfortunately, OCIStmtExecute()
still gives the error related to iters
in this case.
(Please note: the statement handle mystmt
has been properly prepared ahead of time, successfully, with a call to OCIStmtPrepare2()
, and the error handle myerrhp
has also been properly allocated.)
What do I do?
Upvotes: 1
Views: 462
Reputation: 46
Use the OCI_ATTR_STMT_TYPE
instead: It is available right after OCIStmtPrepare
and can be used to crudely determine the type of statement (ie. also if this is a "select" statement).
Upvotes: 3