天天看點

oracle資料庫中的大對象2—— temporary lobs

              到目前為止,我們讨論的都是持久化到資料庫中的lob資料,但是實際應用中,我們有時候并不需要将資料持久化到資料庫中,那麼就需要用到Temporary lob(臨時lob),它就像局部變量一樣,并不持久化到資料庫中。我們将讨論temporary lob和用dbms_lob包來操作它們。

Oracle 8i之後支援建立,解除,通路,更新Temporary lob通過oci(oracle call interface)和dbms_lob包。臨時lob的生命周期是在建立它的session内,但是這種lob可以通過程式提前結束。臨時性的lob操作性能比持久化的lob高,因為它不需要做log,也不需要undo record。而且,當你更新這種lob時候,oracle拷貝整個lob到一個新的segement中。

             Temporary lob開始建立的時候是空的,你不能使用empty_clob(), empty_blob()函數來初始化它。預設地,所有的temporary lob在建立它的session結束的時候被删除。如果程序突然die或database當掉了,那麼也會删除temporary lob,它的存儲空間也會被釋放。

           要注意的是,temporary lob和persistence lob一樣,也是存在資料庫的磁盤檔案中。不要因為它是臨時的lob就認為它是存在記憶體中的。Temporary lob被寫到磁盤中,但是它是不會和特定表的特定lob列關聯的,它寫到磁盤中是存放在session的臨時tablespace中的。是以,你要使用temporary lob,你必須要确認你的臨時tablespace是能夠容納你要建立的temporary lob。

下面具體讨論temporary lob的建立和解除。然後看如何測試一個lob locator指向temporarylob或permanent lob。

1 、建立temporay lob

在使用temporay lob之前,我們必須先建立它。這裡有兩種建立方式:

一種是使用dbms_lob包的createtemporary過程傳入相應的參數建立臨時的clob或blob。定義如下:

PROCEDURE   createtemporary(  lob_loc IN OUT NOCOPY BLOB,

                                                              cache IN BOOLEAN,

                                                              dur IN PLS_INTEGER := 10);

PROCEDURE  createtemporary( lob_loc IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,

                                                           cache IN BOOLEAN,

                                                           dur IN PLS_INTEGER := 10);

參數 描述

Lob_loc—— 将一個lob_locator傳遞給這個lob

cache ——是否将這個lob緩存到buffer cache中去

dur —— Duration(生命周期),這個lob的生命周期,預設是session級别,也就是10,有dbms_lob包中的常量DBMS_LOB.SESSION:=10,還可以指定為程式界别:DBMS_LOB.CALL:=12,也就是程式調用結束的時候釋放此temporaylob占用的空間。

如:

/**

      使用temporay lob

**/

declare

             directions clob;

begin

          dbms_lob.createtemporary(directions,true);

                                            --如果從資料庫中select into的,則為持久化的lob

                                            --select falls_directions into directions from waterfalls where

                                          falls_name='Tannery Falls';

                if(dbms_lob.istemporary(directions)=1) then

                                dbms_output.put_line('directions is temporary!');

              elsif (dbms_lob.istemporary(directions)=0) then

                             dbms_output.put_line('directions is persistence!');

             end if;

end;

第二種方式是,在plsql代碼中申明一個lob變量,然後配置設定一個值給它,那麼就隐式地建立了一個生命周期為session的temporary lob。

DECLARE

             temp_clob CLOB;

             temp_blob BLOB;

BEGIN

                      --Assigning a value to a null CLOB or BLOB variable causes

                     --PL/SQL to implicitly create a session-duration temporary

                      --LOB for you.

         temp_clob :=' http://www.nps.gov/piro/';

        temp_blob := HEXTORAW('7A');

END;

這兩種方式都是可以的,但是建議使用dbms_lob.createtemporary建立,顯示的比較清晰,可讀性也強。

2 、解除temporary lob

将一個temporary lob設為invalid,釋放它的預設存儲空間,通過dbms_lob.freetemporary。

               PROCEDURE freetemporary(lob_loc IN OUT NOCOPY BLOB);

                PROCEDURE freetemporary(lob_loc IN OUT NOCOPY CLOB CHARACTER SET ANY_CS);

free temporary lob     **/

                temp_clob CLOB;

                temp_blob BLOB;

                                   --implict create a clob and a blob in session

              temp_clob :=' http://www.exploringthenorth.com/alger/alger.html';

             temp_blob := HEXTORAW('7A');

                                    --free lob

            DBMS_LOB.FREETEMPORARY(temp_clob);

             DBMS_LOB.FREETEMPORARY(temp_blob);

3、 檢查一個lob是不是temporary

檢查一個lob 是否是temporary,使用dbms_lob 包中的函數isTemporary(lob)來判斷。1表示是temporary lob,否則傳回0 是持久化lob。

4 、管理temporary lob

Temporary lob 的處理不同于持久化的lob,内部lob,對于temporary lob,oracle缺乏很多的支援,如沒有事務管理,不能commit或rollback,不可持續讀,下面列出這些缺點:

        1. 如果處理temporary lob 的時候遇到錯誤,那麼必須釋放lob,重新處理一遍。

        2. 不可将多個lob locator 配置設定給同一個temporary lob。

        3. 如果你修改了有lob locator 指向的temporary lob,那麼oracle會做深度copy。則不同的locator 看到的資料不一樣,為了最小限度深度copy,在調用createtemporary

函數的時候傳入nocopy。

        4. 将temporary lob 變成持久化的lob,必須調用dbms_lob.copy方法。

         5. 一個temporary lob 隻在建立它的session範圍内有效,不能将這個session的temporary locator 傳給另一個session。也就是在另一個session中是不可見的。

Oracle 9i release1 可以通過v$temporary_lob 視圖檢視每個session中緩存了和非緩存了的臨時lob。DBA可以通過v$temporary_lobs 和dba_segements檢視一個session中的多少空間給了temporary lob。

5 、Native lob operations

在oracle9i之前,必須用lob 的包在sql和plsql中處理lob,比如我們需要對一個clob全部轉為大寫,如upper(clob),那是不正确的,在oracle 9i中,clob可以使用大部分的varchar2函數,并且有隐式的實作varchar2和clob之間的互相轉換。在plsql中,但在sql不可以,你可以使用<,>,=操作符。我們可以配置設定一個clob 給varchar2。

             name   CLOB;

            name_upper    CLOB;

            directions     CLOB;

            blank_space VARCHAR2(1) := ' ';

                                  --Retrieve a VARCHAR2 into a CLOB, apply a function to a CLOB

SELECT falls_name, SUBSTR(falls_directions,1,500)

                    INTO name, directions

                            FROM waterfalls

                                  WHERE falls_name = 'Munising Falls';

                                 --Uppercase a CLOB

                 name_upper := UPPER(name);

                                  -- Compare two CLOBs

               IF name = name_upper THEN

                      DBMS_OUTPUT.PUT_LINE('We did not need to uppercase the name.');

               END IF;

                                     --Concatenate a CLOB with some VARCHAR2 strings

               IF INSTR(directions,'Mackinac Bridge') <> 0 THEN

                     DBMS_OUTPUT.PUT_LINE('To get to ' || name_upper || blank_space

                                       || 'you must cross the Mackinac Bridge.');

結果是:

To get to MUNISING FALLS you must cross the Mackinac Bridge.

我們看到Munising Falls被轉為大寫MUNISING FALLS。

注意:這些互相轉換,隻适用于clob,blob,nclob,不适用于bfile。

6 、oracle提供的lob轉換函數

函數 描述

to_clob 将字元資料轉為clob。可以是

varchar2,nvachar2,char,nchar,clob,nclob

to_blob 将raw或long raw轉為blob

to_nclob 和clob 一樣。

to_lob 将raw或long raw轉為clob 或blob

to_raw 将blob 轉為raw