日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

oracle对大对象类型操作:blob,clob,nclob,bfile

發布時間:2024/8/26 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 oracle对大对象类型操作:blob,clob,nclob,bfile 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在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過程:updateclobcreate 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)islobloc clob;c_clob varchar2(32767);amt binary_integer;pos binary_integer;query_str varchar2(1000);beginpos:=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 updatedEXECUTE IMMEDIATE query_str INTO lobloc USING v_id;--from pos position, write 32766 varchar2 into loblocdbms_lob.write(lobloc, amt, pos, c_clob);commit;exceptionwhen others thenrollback;end;l /用法說明:在插入或修改以前,先把其它字段插入或修改,CLOB字段設置為空empty_clob(),然后調用以上的過程插入大于2048到32766個字符。如果需要插入大于32767個字符,編一個循環即可解決問題。查詢CLOB的PL/SQL函數:getclobcreate 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 varchar2islobloc clob;buffer varchar2(32767);amount number := 2000;offset number := 1;query_str varchar2(1000);beginquery_str :='select '||field_name||' from '||table_name||'where '||field_id||'= :id ';--initialize buffer with data to be foundEXECUTE IMMEDIATE query_str INTO lobloc USING v_id;offset:=offset+(v_pos-1)*2000;--read 2000 varchar2 from the bufferdbms_lob.read(lobloc,amount,offset,buffer);return buffer;exceptionwhen no_data_found thenreturn buffer;end;l 用法說明:用select getclob(table_name,field_id,field_name,v_id,v_pos) aspartstr from dual;可以從CLOB字段中取2000個字符到partstr中,編一個循環可以把partstr組合成dbms_lob.getlength(field_name)長度的目標字符串。---------------------------------------------------------------------------------------------------------------------------------

13-4 Lob類型?13.4.1 基本介紹?Oracle和plsql都支持lob(large object) 類型,用來存儲大數量數據,如圖像文件,聲音文件等。Oracle 9i realse2支持存儲最大為4g的數據,oracle 10g realse1支持最大8到128萬億字節的數據存儲,依賴于你的db的block size。?在plsql中可以申明的lob類型的變量如下:? 類型??????? 描述? BFILE??????? 二進制文件,存儲在數據庫外的操作系統文件,只讀的。把此文件當二進制處理。? BLOB??????? 二進制大對象。存儲在數據庫里的大對象,一般是圖像聲音等文件。? CLOB??????? 字符型大對象。一般存儲大數量文本信息。存儲單字節,固定寬度的數據。? NCLOB??????? 字節字符大對象。存儲單字節大塊,多字節固定寬度,多字節變寬度數據。? Oracle將lob分類為兩種:? 1.存儲在數據庫里的,參與數據庫的事務。BLOB,CLOB,NCCLOB。? 2.存儲在數據庫外的BFILE,不參與數據庫的事務,也就是不能rollback或commit等,它依賴于文件系統的數據完整性。? LONG和LONG RAW這兩種數據類型也是存儲字符的,但是有系列的問題,不建議使用,這里也就不討論了。? 13.4.2 LOB的使用? 本部分不討論lob的所有細節,只討論lob的基本原理和在plsql中的基本使用,為plsql開發使用lob提供一個基礎性指導。? 本部分使用的表是:? /**? table script? **/? CREATE TABLE waterfalls (?falls_name VARCHAR2(80),--name?falls_photo BLOB,--照片?falls_directions CLOB,--文字?falls_description NCLOB,--文字?falls_web_page BFILE);--指向外部的html頁面? /???????這個表我們并不需要clob和nclob兩個,只取一就可以,這里全部定義只是為了演示使用。? 1.??????? 理解LOB的Locator? 表中的Lob類型的列中存儲的只是存儲指向數據庫中實際存儲lob數據的一個指針。? 在plsql中申明了一個lob類型的變量,然后從數據庫中查詢一個lob類型的值分配給變量,也只是將指針復制給了它,那么這個變量也會指向數據庫中實際存放lob數據的地方。如:? --understanding lob locators?DECLARE?photo BLOB;?BEGIN?SELECT falls_photo?INTO photo?FROM waterfalls?WHERE falls_name='Dryer Hose';? 見下圖:? Lob工作原理圖解?從上面的圖可以看出,要處理lob數據,必須先獲得lob locators。我們可以通過一個select語句獲取,當賦值給lob變量的時候,它也獲得同樣的lob locators。我們在plsql中處理可以使用dbms_lob包,里面內置了很多過程和函數來讀取和修改我們的lob數據。下面給出處理lob數據的一般方法。? 1.??????? 通過select語句獲取一個lob locator。? 2.??????? 通過調用dbms_lob.open打開lob。? 3.??????? 調用dbms_lob.getchunksize獲得最佳讀寫lob值。? 4.??????? 調用dbms_lob.getlength獲取lob數據的字節值。? 5.??????? 調用dbms_lob.read獲取lob數據。? 6.??????? 調用dbms_lob.close關閉lob。???????? 2.??????? Empty lob and Null lob? Empty的意思是我們已經獲取了一個lob locator,但是沒有指向任何lob數據。Null是定義了一個變量,但是沒有獲得lob locator。對lob類型的處理和其他類型不一樣。如下面的例子:? /* null lob example*/? declare?directions clob;--定義了,但是沒有分配值,為null?begin?if directions is null then?dbms_output.put_line('directions is null');?else?dbms_output.put_line('directions is not null');?end if;???????end;? /? DECLARE?directions CLOB;--定義一個,并且分配值?BEGIN?--刪除一行?DELETE?FROM waterfalls?WHERE falls_name='Munising Falls';?--插入一行通過使用 EMPTY_CLOB(? ) to 建立一個lob locator?INSERT INTO waterfalls?(falls_name,falls_directions)?VALUES ('Munising Falls',EMPTY_CLOB(? ));?--獲得lob locator,上面插入的數據,因為我們插入的是一個empty_clob(),那么lob locator不指向任何數據,雖然給變量分配了只?SELECT falls_directions?INTO directions?FROM waterfalls?WHERE falls_name='Munising Falls';?IF directions IS NULL THEN?DBMS_OUTPUT.PUT_LINE('directions is NULL');?ELSE?DBMS_OUTPUT.PUT_LINE('directions is not NULL');--打印此句?END IF;?DBMS_OUTPUT.PUT_LINE('Length = '?|| DBMS_LOB.GETLENGTH(directions));--結果為o?END;? 注意:? 1.??????? 上面例子中的empty_clob()是oracle的內置函數,創建了一個lob locator。但是我們沒有讓它指向任何數據,所以是empty。而且通過select語句給變量directions分配了lob locator,所以不是null,但是length為0,故為empty。? 2.??????? 在基本類型中,我們判斷一個變量是不是有數據,只要is null就可以了。但是在lob類型中我們從以上的例子看出來是不正確的。Lob首先必須判斷is null看是否分配lob locator,如果分配了還需要進一步檢查length是否為0,看是否是empty,所以完整的是下面這樣:? IF some_clob IS NULL THEN?--如果is null為true表示未分配,肯定沒有數據?ELSEIF DBMS_LOB.GETLENGTH(some_clob) = 0 THEN?--分配了length為0,也沒有數據?ELSE?--有數據?END IF;? 3.建立LOB?在上面我們使用empty_clob()建立了一個空的clob,lob locator只是一個指針,真正的數據是存儲在磁盤中或數據庫文件中。我們先建立一個空的clob,然后我們可以update來讓變量真正指向有數據的lob。Empty_clob()可以用來處理clob和nclob。在oracle 8i中可以使用temporary lob達到同樣的效果。

?

4.向LOB里寫入數據?當獲得一個有效的lob locator之后,就可以使用dbms_lob包的下列procedure向lob中寫入數據。?DBMS_LOB.WRITE:允許自動寫入數據到lob中。?DBMS_LOB.WRITEAPPEND:向lob的末尾寫入數據。? --write lob? DECLARE?directions CLOB;?amount BINARY_INTEGER;?offset INTEGER;?first_direction VARCHAR2(100);?more_directions VARCHAR2(500);?BEGIN?--Delete any existing rows for 'Munising Falls' so that this?--example can be executed multiple times?DELETE?FROM waterfalls?WHERE falls_name='Munising Falls';?--Insert a new row using EMPTY_CLOB(? ) to create a LOB locator?INSERT INTO waterfalls?(falls_name,falls_directions)?VALUES ('Munising Falls',EMPTY_CLOB(? ));?--Retrieve the LOB locator created by the previous INSERT statement?SELECT falls_directions?INTO directions?FROM waterfalls?WHERE falls_name='Munising Falls';?--Open the LOB; not strictly necessary, but best to open/close LOBs.?DBMS_LOB.OPEN(directions, DBMS_LOB.LOB_READWRITE);?--Use DBMS_LOB.WRITE to begin?first_direction := 'Follow I-75 across the Mackinac Bridge.';?amount := LENGTH(first_direction);? --number of characters to write?offset := 1; --begin writing to the first character of the CLOB?DBMS_LOB.WRITE(directions, amount, offset, first_direction);?--Add some more directions using DBMS_LOB.WRITEAPPEND?more_directions := ' Take US-2 west from St. Ignace to Blaney Park.'?|| ' Turn north on M-77 and drive to Seney.'?|| ' From Seney, take M-28 west to Munising.';?DBMS_LOB.WRITEAPPEND(directions,?LENGTH(more_directions), more_directions);?--Add yet more directions?more_directions := ' In front of the paper mill, turn right on H-58.'?|| ' Follow H-58 to Washington Street. Veer left onto'?|| ' Washington Street. You''ll find the Munising'?|| ' Falls visitor center across from the hospital at'?|| ' the point where Washington Street becomes'?|| ' Sand Point Road.';?DBMS_LOB.WRITEAPPEND(directions,?LENGTH(more_directions), more_directions);?--Close the LOB, and we are done.?DBMS_LOB.CLOSE(directions);?END;? /? 在這個例子里,我們使用了write 和writeappend這兩個過程來插入數據到lob中。因為開始的時候,我們插入了一個空的lob locator。要注意一點,我們最后使用了dbms_lob.close方法關閉lob。這是一個好的方法,特別是在處理oracle text的時候,任何oracle text domain和function-based indexes被update是在wirte和writeappend的時候調用的,而不是在close的時候被update的。???????? 我們向lob中寫入數據的時候,沒有必要更新表中的列。因為它保存的只是一個locator,我們的變量也獲得同樣的locator,當我們寫入數據去lob的時候,locator并沒有改變。改變的只是locator指向的物理數據。? 在sqlplus中顯示上面的例子:?SQL> SET LONG 2000????????????SQL> COLUMN falls_directions WORD_WRAPPED FORMAT A70?SQL> SELECT falls_directions?2? FROM waterfalls?3? WHERE falls_name='Munising Falls';? 其中set long 2000是顯示2000個字符。Word_wrappend是自動換行。? 5.從lob中讀取數據?步驟:a.通過select查詢獲得lob locator初始化lob變量。2.調用dbms_lob.read過程讀取lob數據。? 下面是dbms_lob.read過程的定義,注意參數.??? PROCEDURE read(lob_loc IN??????????? BLOB,? --初始化后的lob變量lob locator?amount? IN OUT NOCOPY INTEGER,--讀取的數量(clob為字符數,blob,bfile是字節數)?offset? IN??????????? INTEGER,--開始讀取位置?buffer? OUT?????????? RAW);--讀到的數據,raw要顯示用轉換函數,見bfile? PROCEDURE read(lob_loc IN??????????? CLOB???? CHARACTER SET ANY_CS,?amount? IN OUT NOCOPY INTEGER,?offset? IN??????????? INTEGER,?buffer? OUT?????????? VARCHAR2 CHARACTER SET lob_loc%CHARSET);?PROCEDURE read(file_loc IN???????????? BFILE,?amount?? IN OUT NOCOPY? INTEGER,?offset?? IN???????????? INTEGER,?buffer?? OUT??????????? RAW);? 下面是一個讀取clob的例子:? --從lob中讀取數據? DECLARE?directions CLOB;?directions_1 VARCHAR2(300);?directions_2 VARCHAR2(300);?chars_read_1 BINARY_INTEGER;?chars_read_2 BINARY_INTEGER;?offset INTEGER;?BEGIN?--首先獲得一個lob locator?SELECT falls_directions?INTO directions?FROM waterfalls?WHERE falls_name='Munising Falls';?--記錄開始讀取位置?offset := 1;?--嘗試讀取229個字符,chars_read_1將被實際讀取的字符數更新?chars_read_1 := 229;?DBMS_LOB.READ(directions, chars_read_1, offset, directions_1);?--當讀取229個字符之后,更新offset,再讀取225個字符?IF chars_read_1 = 229 THEN?offset := offset + chars_read_1;--offset變為offset+chars_read_1,也就是從300開始?chars_read_2 := 255;?DBMS_LOB.READ(directions, chars_read_2, offset, directions_2);?ELSE?chars_read_2 := 0;--否則后面不在讀取?directions_2 := '';?END IF;?--顯示讀取的字符數?DBMS_OUTPUT.PUT_LINE('Characters read = ' ||?TO_CHAR(chars_read_1+chars_read_2));?--顯示結果?DBMS_OUTPUT.PUT_LINE(directions_1);?dbms_output.put_line(length(directions_1));?DBMS_OUTPUT.PUT_LINE(directions_2);?dbms_output.put_line(length(directions_2));?END;?/? Dbms_lob.read的第2個參數是傳遞要讀取的數量。對于clob是字符數,blob和bfile都是字節數。它是隨著讀取的數目自動更新的,offset不會更新。所以分布讀取需要手動更新offset,下個offset是上一個offset+讀取的數量。我們可以通過dbms_lob.get_length(lob_locator)獲得這個lob的長度,結果clob是字符數,blob和bfile是字節數,然后分布讀取。? 13.4.3 使用Bfile?Bfile和clob,nclob,blob是不同的。Bfile是外部的lob類型,其他三個是oracle內部的lob類型,它們至少有三點主要不同的地方:? 1.??????? bfile的值是存在操作系統的文件中,而不是數據庫中。? 2.??????? bfile不參與數據庫事務操作。也就是改變bifle不能commit或rollback。但是改變bfile的locator可以commit或rollback。? 3.??????? bfile在plsql和oracle中是只讀的,不允許寫。你必須生成一個外部的操作系統文件讓bfile locator能夠完全指向它。? 在plsql中使用bifle,仍然需要lob locator,只不過是一個目錄和文件的別名,你可以使用biflename函數獲得一個bfile locator。使用create or replace directory [alias] as ‘file locator directory’,你必須具有CREATE ANY DIRECTORY權限才能使用。如:? CREATE DIRECTORY bfile_data AS 'c:PLSQL BookCh12_Misc_Datatypes';?GRANT READ ON DIRECTORY bfile_data TO gennick;? --讀的權限給這個用戶。? 通過all_directory查找目錄信息。

總結

以上是生活随笔為你收集整理的oracle对大对象类型操作:blob,clob,nclob,bfile的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。