3

OCIStmtPrepare()とを使用する場合OCIBindByName()、名前でバインドし、そのバインドの位置を として取得する方法はありintますか? OCIStmtGetBindInfo()しないようです。ありがとう!

4

1 に答える 1

2

それを行う簡単な方法はないようです。バインドハンドルでOCI_ATTR_HANDLE_POSITION使用して、文書化されていないものを使用してみました(ヘルプドキュメントでは見つかりませんでしたが、oci.hヘッダーにあります) :OCIAttrGet()

ub4 bpos = 0;
OCIBind *bindp;
OCIAttrGet(bindp, OCI_HTYPE_BIND, &bpos, 0, OCI_ATTR_HANDLE_POSITION, errhp);

残念ながら、それは位置的にバインドしたバインド ハンドルでは機能するようですが、名前でバインドしたものに対しては 0 を返します。

したがって、OCIStmtGetBindInfo()呼び出しを使用してバインド変数名の配列を埋め、それを反復処理して、バインド名をバインド変数の値と比較することにより、名前付きバインドごとに位置を見つける必要があるようです。 names 配列 (値は大文字になります):

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]);
}

ステートメント内の複数のプレースホルダーについて注意すべき興味深い点の 1 つは、ステートメントが無名ブロックであるかどうかによって動作が異なることです。あれは:

insert into foo (bar, baz) values (:bar, :bar)

found出力変数に 2 (および 2 つのバインドの情報を含む配列) を入力しますが、次のようになります。

begin insert into foo (bar, baz) values (:bar, :bar); end;

出力変数を 1 で埋めますfound(および 1 バインドの情報を含む配列)。OCIBindByName()それにもかかわらず、いずれの場合でも、1 回の呼び出しで両方がバインドされます。

于 2011-06-08T01:04:12.083 に答える