關於oracle中blob欄位的錄入問題

fengzj發表於2009-03-23

  在oracle中,有4個大物件(lobs)型別可用,分別是blob,clob,bfile,nclob。
  下面是對lob資料型別的簡單介紹。
   blob:二進位制lob,為二進位制資料,最長可達4GB,存貯在資料庫中。
   clob:字元lob,字元資料,最長可以達到4GB,存貯在資料庫中。
   bfile:二進位制檔案;存貯在資料庫之外的只讀型二進位制資料,最大長度由作業系統限制。
   nclob:支援對位元組字符集合(nultibyte characterset)的一個clob列。
  對於如何檢索和操作這些lob資料一直是oracle資料庫開發者經常碰到的問題。下面我將在oracle對lob資料處理的一些方法和技巧,介紹給讀者,希望能夠對讀者以後的開發有所幫助。
  
  oracle中可以用多種方法來檢索或操作lob資料。通常的處理方法是通過dbms_lob包。
  其他的方法包括使用api(application programminginterfaces)應用程式介面和oci(oracle call interface)oracle呼叫介面程式。
   一、在oracle開發環境中我們可以用dbms_lob包來處理!dbms_lob包功能強大,簡單應用。既可以用來讀取內部的lob物件,也可以用 來處理bfile物件。但處理兩者之間,還有一點差別。處理內部lob物件(blob,clob)時,可以進行讀和寫,但處理外部lob物件bfile 時,只能進行讀操作,寫的操作可以用pl/sql處理。另外用sql也可以處理lob,但要注意sql僅可以處理整個lob,不能操作lob的資料片。
  
  在dbms_lob包中內建了read(),append,write(),erase(),copy(),getlength(),substr()等函式,可以很方便地操作lob物件。這裡不做深入討論,讀者可以參看相關的書籍。
  
  對於pl/sql,下面介紹一種技巧,用動態的pl/sql語句處理clob物件來傳替表名!
  example 1.
  動態PL/SQL,對CLOB欄位操作可傳遞表名table_name,表的唯一標誌欄位名field_id,clob欄位名field_name記錄號v_id,開始處理字元的位置v_pos,傳入的字串變數v_clob
  
  修改CLOB的PL/SQL過程:updateclob
  create or replace procedure updateclob(
  table_name in varchar2,
  field_id in varchar2,
  field_name in varchar2,v_id in number,
  v_pos in number,
  v_clob in varchar2)
  is
  lobloc clob;
  c_clob varchar2(32767);
  amt binary_integer;
  pos binary_integer;
  query_str varchar2(1000);
  begin
  pos:=v_pos*32766+1;
  amt := length(v_clob);
  c_clob:=v_clob;
  query_str :='select '||field_name||'from '||table_name||'
  where '||field_id||'= :id for update ';
  --initialize buffer with data to be inserted or updated
  EXECUTE IMMEDIATE query_str INTO lobloc USING v_id;
  --from pos position, write 32766 varchar2 into lobloc
  dbms_lob.write(lobloc, amt, pos, c_clob);
  commit;
  exception
  when others then
  rollback;
  end;
  l /用法說明:
  在插入或修改以前,先把其它欄位插入或修改,CLOB欄位設定為空empty_clob(),
  然後呼叫以上的過程插入大於2048到32766個字元。
  如果需要插入大於32767個字元,編一個迴圈即可解決問題。
  查詢CLOB的PL/SQL函式:getclob
  create or replace function getclob(
  table_name in varchar2,
  field_id in varchar2,
  field_name in varchar2,
  v_id in number,
  v_pos in number) return varchar2
  is
  lobloc clob;
  buffer varchar2(32767);
  amount number := 2000;
  offset number := 1;
  query_str varchar2(1000);
  begin
  query_str :='select '||field_name||' from '||table_name||'
  where '||field_id||'= :id ';
  --initialize buffer with data to be found
  EXECUTE IMMEDIATE query_str INTO lobloc USING v_id;
  offset:=offset+(v_pos-1)*2000;
  --read 2000 varchar2 from the buffer
  dbms_lob.read(lobloc,amount,offset,buffer);
  return buffer;
  exception
  when no_data_found then
  return buffer;
  end;
  l 用法說明:
  用select getclob(table_name,field_id,field_name,v_id,v_pos) as
  partstr from dual;
  可以從CLOB欄位中取2000個字元到partstr中,
  編一個迴圈可以把partstr組合成dbms_lob.getlength(field_name)長度的目標字串。
  二、對於在其他不同的開發環境,例如vc,vb,pb,java等環境下對lob的處理,處理方法不盡相同,在這裡將簡要舉幾個例子來說明不在oracle開發環境下對lob的處理。
  
  (一) 在pb中的處理
  exampler 2.
  string ls_path,ls_filename,ls_jhdh
  long ll_num,ll_count,rtn
  blob ole_blob
  ll_num=dw_lb.getrow()
  if ll_num>0 then ls_jhdh=dw_lb.object.ct_njhdh[ll_num]
  select count(*) into :ll_count from sj_jh_jhfjb where
  ct_jhdlxbh='1' and ct_jhdh=:ls_jhdh and ct_jdlxbh=:is_jdlx;
  if ll_count>0 then
  rtn=messagebox("提示","是否要修改此附件",question!,yesno!,1)
  if rtn=1 then
  SELECTBLOB ct_jhfjnr INTO le_blob from sj_jh_jhfjb where
  ct_jhdlxbh='1' and ct_jhdh=:ls_jhdh and ct_jdlxbh=:is_jdlx;
  ole_1.objectdata =ole_blob
  If ole_1.activate(offsite!) <> 0 Then
  Messagebox("OLE Activate","不能啟用")
  Return -1
  end If
  end if
  else
  messagebox("提示","沒有附件")
  end if
  end if

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/219982/viewspace-578024/,如需轉載,請註明出處,否則將追究法律責任。

相關文章