4

多くの潜在的に大きな文字列のFAT行を含むテーブルがあるとします。

create table t (s1 varchar2(4000), ..., sN varchar2(4000))

直接バインドを使用してこれらの列をフェッチする方法を知っています。

std::vector<char> buf1(4000, '\0');
OCIDefineByPos(..., 1, &buf1.front(), sb4(buf1.size()),
               SQLT_CHR, &ind1, &rlen1, 0, OCI_DEFAULT);
foreach 行 {
  std::string actual1(buf1.begin(), buf1.begin() + rlen1);
}

このアプローチの問題点は、すべての列の最大サイズをアプリオリに知る必要があることです (記述でそれを知ることもできますが、それはより多くの作業です)。また、各セルにデータが含まれている場合、多くの大きなバッファーを事前に割り当てる必要があります。実際にははるかに小さいです。

OCI_DEFAULT を OCI_DYNAMIC_FETCH に置き換え、OCI_DEFAULT を OCI_DYNAMIC_FETCH に置き換え、OCIDefineDynamic を使用してコールバックを登録し、動的にバッファを提供するために OCI_FIRST_PIECE で呼び出されましたが、ここでも、提供されたバッファは十分な大きさでなければならず、OCI はそうではありません。フェッチされた varchar2 列の実際のサイズを提供して、必要なだけ動的にバッファのサイズを変更できるようにするか、短すぎるバッファを受け入れて OCI_NEXT_PIECE で再度呼び出して、値を蓄積できるようにしますチャンクごとに。

今私は体系的に取得しますORA-01406: fetched column value was truncated

動的に割り当てられたフェッチ バッファの例を教えてください。ティア、 --DD

4

1 に答える 1

0

OCIStringSQLT_VSTの代わりにフェッチSQLT_CHRして依存することで、これを行うことができると思います。メモリ割り当ては OCI 内で自動的に管理され、実際にそのポインタを取得します。次に、実際の値のサイズを取得してコピーするか、 を介して通常のポインタとして使用できます。OCIStringSize()malloc()char*OCIStringPtr()

于 2012-02-08T19:20:57.193 に答える