2011-12-16 82 views
4

給定一個表 FAT行許多潛在的大串的:當獲取varchar2列值時,是否可以動態調整緩衝區大小?

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

與此問題方法是它需要先驗地知道所有列的最大大小(描述也可以告訴我,但這是更多的工作),但也強制預分配許多大緩衝區時,數據co在實踐中,每個單元格中的瑕疵都要小得多。

我一直在使用分段取嘗試,與OCI_DYNAMIC_FETCH更換OCI_DEFAULT和註冊使用OCIDefineDynamic我的回調,而我得到調用OCI_FIRST_PIECE,動態地提供緩衝,但在這裏提供的緩衝區必須足夠大,正如人們所期望的那樣,OCI沒有提供獲取的varchar2列的實際大小,以便能夠動態調整緩衝區的大小,或者只是接受太短的緩衝區,並使用OCI_NEXT_PIECE再次呼叫我,所以我可以通過塊來累積值塊。

現在我得到系統ORA-01406: fetched column value was truncated

任何人都可以提供動態分配取緩衝區的例子嗎? TIA,--DD

+1

你是怎麼解決這個問題的?你有一個例子嗎?我面對同一個。謝謝。 – Toru 2015-03-21 17:48:15

回答

0

我相信你可以通過提取SQLT_VST而不是SQLT_CHR並依靠OCIString來做到這一點。內存分配是在OCI內部自動管理的,並且你實際上得到了一個指向它的指針。然後你可以通過OCIStringSize()malloc()得到實際值的大小並複製它,或者只是通過OCIStringPtr()將它作爲常規char*指針使用。

相關問題