Как получить тип оператора OCI_ATTR_SQLFNCODE * перед * OCIStatementExecute ()? - PullRequest
1 голос
/ 10 марта 2012

Мне нужно знать, как получить тип оператора подготовленного дескриптора оператора в OCI.

Дилемма заключается в следующем.Четвертый аргумент OCIStmtExecute() - iters - не может быть 0, если оператор не является SELECT, но должен быть 0, если оператор равен SELECT (и определить нельзя заранее).Из документации OCI 10g для OCIStmtExecute:

Для операторов, отличных от SELECT, число выполнений этого оператора равно iters - rowoff.

Для операторов SELECT:если iters отлично от нуля, то для дескриптора оператора должны быть определены определения.Выполнение извлекает свои строки в эти предопределенные буферы и предварительно выбирает больше строк в зависимости от количества строк предварительной выборки.Если вы не знаете, сколько строк извлечет оператор SELECT, установите значение iters на ноль.

Эта функция возвращает ошибку, если значение iters = 0 для операторов, не являющихся SELECT.

Дляоператор, такой как SELECT * ..., невозможно узнать, какие столбцы даже являются до получения информации describe из дескриптора оператора, который доступен только после вызова OCIStmtExecute().(Таким образом, невозможно сделать defines для дескриптора оператора раньше времени.) Поэтому я должен передать 0 для iters, если (неизвестный) тип оператора равен SELECT.Но если (неизвестный) тип оператора равен , а не SELECT, OCI возвращает ошибку, если iters равно 0 (как указано в документации).

Документированный способПолучить тип оператора (SELECT или нет) можно, запросив атрибут дескриптора оператора следующим образом:

ub2 statementType = 0;
OCIAttrGet(mystmt, OCI_HTYPE_STMT, (dvoid*)(&statementType), NULL, OCI_ATTR_SQLFNCODE, myerrhp);

К сожалению, эта функция всегда возвращает 0 дляstatementType до после вызова OCIStmtExecute().

Я нахожусь в ловушке-22.Я должен позвонить OCIAttrGet(), прежде чем позвонить OCIStmtExecute(), чтобы получить тип оператора, чтобы правильно установить iters.Тем не менее, я должен вызвать OCIStmtExecute(), прежде чем OCIAttrGet() будет успешным.

Я попытался вызвать OCIStmtExecute() дважды, впервые передав OCI_DESCRIBE_ONLY для последнего параметра (mode).К сожалению, OCIStmtExecute() still выдает ошибку, связанную с iters в этом случае.

(Обратите внимание: дескриптор оператора mystmt был должным образом подготовлен заранее, успешно,с вызовом OCIStmtPrepare2() и дескриптором ошибки myerrhp также был правильно выделен.)

Что мне делать?

1 Ответ

3 голосов
/ 23 ноября 2012

Вместо этого используйте OCI_ATTR_STMT_TYPE: оно доступно сразу после OCIStmtPrepare и может использоваться для грубого определения типа оператора (т. Е. Также, если это оператор "выбор").

...