第一次接近Oracle DB中的LOB,偶然發現了一些讓我感到困惑的東西。EXEC SQL LOB寫入APPEND與輪詢(寫第一個,寫下一個,最後寫)
我必須插入一個BLOB成我插入到錶行的一列,用Pro*C
。 The documentation says我有兩種可能的選擇。
- 編寫吊射一次全部,如果它符合緩衝區,以
EXEC SQL WRITE
ONE
零碎寫的吊射,如果緩衝區太小,用的是什麼文件調用輪詢,與做出來的這3個步驟的序列:
EXEC SQL WRITE
FIRST
EXEC SQL WRITE
NEXT
n倍EXEC SQL WRITE
LAST
但是,我發現我可以代替輪詢方法如簡單地與EXEC SQL WRITE
APPEND
Ñ描繪由文檔+2倍,使循環更加簡單,直觀並使其更容易o處理錯誤處理。
因此,而不是寫這樣的事情(從the documentation拍攝):
if (filelen > MAXBUFLEN)
nbytes = MAXBUFLEN ;
else
nbytes = filelen ;
fread((void *)buffer, (size_t)nbytes, (size_t)1, fp) ;
remainder = filelen - nbytes ;
if (remainder == 0)
{
EXEC SQL LOB WRITE ONE :amt
FROM :buffer INTO :blob AT :offset ;
}
else
{
EXEC SQL LOB WRITE FIRST :amt
FROM :buffer INTO :blob AT :offset ;
last = FALSE ;
EXEC SQL WHENEVER SQLERROR DO break ;
do
{
if (remainder > MAXBUFLEN)
nbytes = MAXBUFLEN ;
else
{
nbytes = remainder ;
last = TRUE ;
}
if (fread((void *)buffer, (size_t)nbytes, (size_t)1, fp) != 1)
last = TRUE ;
if (last)
{
EXEC SQL LOB WRITE LAST :amt
FROM :buffer INTO :blob ;
}
else
{
EXEC SQL LOB WRITE NEXT :amt
FROM :buffer INTO :blob;
}
remainder -= nbytes ;
}
while (!last && !feof(fp)) ;
}
,可以寫只是這樣的:
while ((nbytes = remainder < MAXBUFLEN ? remainder : MAXBUFLEN))
{
if (fread(buffer, nbytes, 1, fp) != 1) {
/* Handle error somehow */
break;
}
EXEC SQL LOB WRITE APPEND :nbytes
FROM :buffer WITH LENGTH :nbytes INTO blob;
remainder -= nbytes;
}
我徹底的測試第二種方法沒有注意到任何問題所以我很想知道:
- 有有什麼不對嗎第二種方法,蔑視我的注意力?
- 如果沒關係要像第二種方法一樣進行,那麼需要使用3個步驟(如the documentation)的輪詢機制來解釋?
該文檔指出,必須使用** ENABLE **指令明確啓用緩衝,這在給出的示例中沒有完成。 此外,我正在進行順序寫入,總是附加在以前的結尾:它似乎不符合「多個讀取/寫入到LOB」的描述,還是它? 在上面的例子中,文檔描述的3步輪詢方法與單** APPEND **步驟相比有什麼優勢? –
@FabioA。我認爲如果您使用LBS,那麼您可能無法使用APPEND方法(但其他方法可以)。嘗試啓用磅,看看是否是這種情況。 – tbone
@tbone的確,只是嘗試過,並不能說在啓用緩衝的情況下無法在LOB上執行操作。然而,看不到優點:如果我必須使用LBS將文件複製到LOB零碎,然後將其全部清除到數據庫,爲什麼不使用與C文件本身一樣大的緩衝區並將其寫入在「LITE ONE」中的一個塊中的LOB中? –