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     **/

DECLARE
                temp_clob CLOB;
                temp_blob BLOB;
BEGIN
                                   --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);
END;


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。


DECLARE
             name   CLOB;
            name_upper    CLOB;
            directions     CLOB;
            blank_space VARCHAR2(1) := ' ';
BEGIN
                                  --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.');
               END IF;
END;


结果是:
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

你可能感兴趣的:(oracle数据库中的大对象2—— temporary lobs)