给定一个包含许多可能很大字符串的 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 row { std::string actual1(buf1.begin(), buf1.begin() + rlen1); }
这种方法的问题在于它需要知道所有列max-size的先验(一个描述也可以告诉我,但这更多的工作),但也强制在包含数据时预先分配许多大缓冲区在每个细胞中,实际上要小得多。
我尝试过使用分段提取,用OCI_DYNAMIC_FETCH替换OCI_DEFAULT并使用OCIDefineDynamic注册我的回调,然后我用OCI_FIRST_PIECE调用,以动态提供缓冲区,但是这里提供的缓冲区必须足够大,并且OCI没有提供所获取的varchar2列的实际大小,正如人们所预料的那样,能够根据需要动态调整缓冲区的大小,或者只接受太短的缓冲区并使用OCI_NEXT_PIECE再次调用我,这样我就可以按块积累值块。
现在我系统地得到ORA-01406: fetched column value was truncated
有人能提供动态分配的获取缓冲区的示例吗? TIA,--DD
答案 0 :(得分:0)
我相信你可以通过提取SQLT_VST
代替SQLT_CHR
并依赖OCIString来实现这一目标。内存分配在OCI内自动管理,实际上你得到一个指向它的指针。然后,您可以使用OCIStringSize()
和malloc()
来获取实际值的大小并将其复制,或者只是通过char*
将其用作常规OCIStringPtr()
指针。