Кажется, нет простого способа сделать это. Я попытался использовать недокументированное (как я не смог найти его в справочной документации, но оно есть в заголовке oci.h) OCI_ATTR_HANDLE_POSITION
с использованием OCIAttrGet()
на дескрипторе связывания:
ub4 bpos = 0;
OCIBind *bindp;
OCIAttrGet(bindp, OCI_HTYPE_BIND, &bpos, 0, OCI_ATTR_HANDLE_POSITION, errhp);
К сожалению, похоже, что это работает для ручек связывания, которые вы привязали позиционно, но возвращает 0 для любых, с которыми вы связаны именем.
Так что, похоже, вам придется использовать вызов OCIStmtGetBindInfo()
, чтобы он заполнил массив имен переменных связывания, а затем перебрал его, чтобы найти позиции для каждой именованной привязки, либо сравнивая имя связывания со значениями в массиве имен переменных связывания (значения которого будут в верхнем регистре):
sb4 found = 0;
text* bvns[100];
ub1 bvnls[100];
text* invs[100];
ub1 invls[100];
ub1 dupls[100];
OCIBind* bhnds[100];
OCIStmtGetBindInfo(stmthp, errhp, (ub4)100, (ub4)1, &found, bvns, bvnls, invs, invls, dupls, bhnds);
for (unsigned int col = 0; col < found; col++)
{
printf("%p is bound to name: %s", bhnds[col], bvns[col]);
}
Одна интересная вещь, которую следует отметить в отношении нескольких заполнителей в выражении, заключается в том, что он ведет себя по-разному, если ваше утверждение является анонимным блоком или нет. То есть:
insert into foo (bar, baz) values (:bar, :bar)
заполнит вашу found
выходную переменную 2 (а массивы с информацией для 2 привязок), тогда как:
begin insert into foo (bar, baz) values (:bar, :bar); end;
Заполнит вашу found
выходную переменную 1 (а массивы с информацией для 1 привязки).
Тем не менее, один вызов OCIBindByName()
будет связывать оба в любом случае.