2012-10-04 24 views
0

第一次接近Oracle DB中的LOB,偶然發現了一些讓我感到困惑的東西。EXEC SQL LOB寫入APPEND與輪詢(寫第一個,寫下一個,最後寫)

我必須插入一個BLOB成我插入到錶行的一列,用Pro*CThe documentation says我有兩種可能的選擇。

  1. 編寫吊射一次全部,如果它符合緩衝區,以EXEC SQL WRITEONE
  2. 零碎寫的吊射,如果緩衝區太小,用的是什麼文件調用輪詢,與做出來的這3個步驟的序列:

    1. EXEC SQL WRITEFIRST
    2. EXEC SQL WRITENEXT n倍
    3. EXEC SQL WRITELAST

但是,我發現我可以代替輪詢方法如簡單地與EXEC SQL WRITEAPPENDÑ描繪由文檔+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; 
} 

我徹底的測試第二種方法沒有注意到任何問題所以我很想知道:

  1. 有什麼不對嗎第二種方法,蔑視我的注意力?
  2. 如果沒關係要像第二種方法一樣進行,那麼需要使用3個步驟(如the documentation)的輪詢機制來解釋?

回答

0

如果使用LBS(LOB緩衝子系統)進行適當的緩衝,可能會有一些優點。甲骨文解釋 -

緩衝具有這些優點,特別是對於一個 客戶端做了很多小的讀取和寫入的 特定區域的LOB上的應用程序:

  1. 的LBS減少往返行程服務器,因爲您用多次讀取/寫入LOB來填充緩衝區,然後在執行FLUSH指令時寫入 服務器。

  2. 緩衝還會減少服務器上的LOB更新總數。這會創建更好的LOB性能並節省磁盤空間。

滾動到你的鏈接LOB Buffering Subsystem部分閱讀更多。

+0

該文檔指出,必須使用** ENABLE **指令明確啓用緩衝,這在給出的示例中沒有完成。 此外,我正在進行順序寫入,總是附加在以前的結尾:它似乎不符合「多個讀取/寫入到LOB」的描述,還是它? 在上面的例子中,文檔描述的3步輪詢方法與單** APPEND **步驟相比有什麼優勢? –

+0

@FabioA。我認爲如果您使用LBS,那麼您可能無法使用APPEND方法(但其他方法可以)。嘗試啓用磅,看看是否是這種情況。 – tbone

+0

@tbone的確,只是嘗試過,並不能說在啓用緩衝的情況下無法在LOB上執行操作。然而,看不到優點:如果我必須使用LBS將文件複製到LOB零碎,然後將其全部清除到數據庫,爲什麼不使用與C文件本身一樣大的緩衝區並將其寫入在「LITE ONE」中的一個塊中的LOB中? –