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