在
前面我们提到过 Temporary LOB,它跟我们先前介绍的 LOB 不一样,先前的可以称之为 Persistent LOB。有时候,我们需要 Temporary LOB,就像其它类型的本地变量一样,在会话中使用,而不用持久化到数据库中。
从 Oracle8i 开始,通过 OCI (Oracle Call Interface) 和 DBMS_LOB 可以实现 Temporary LOB 的创建、释放、访问和更新。Temporary LOB 的默认生存期是其所在的会话的生存期,但可以被手工释放。使用 Temporary LOB,不会产生 REDO 和 UNDO 信息,所以能提供更好的性能。
刚创建时,Temporary LOB 就是空的,不需要再使用 EMPTY_BLOB 或 EMPTY_CLOB 函数对其初始化。若会话异常中断,或数据库宕机,则 Temporary LOB 所占用的空间也会立即释放。
和 Persistent LOB 一样,Temporary LOB 数据也是保存在数据库中的,不要以为它是在内存中存在的。但 Temporary LOB 数据并不跟任何表的列相关联,而是保存在该会话所占用的临时表空间中。所以使用 Temporary LOB,你得保证临时表空间足够存储它。
1. 创建
有两种创建方法,一种是使用系统过程 DBMS_LOB.CREATETEMPORARY 显式创建,一种是直接赋值隐式创建。
* 显式创建
DBMS_LOB.CREATETEMPORARY (
lob_loc IN OUT NOCOPY [ BLOB | CLOB CHARACTER SET ANY_CS ], cache IN BOOLEAN, dur IN PLS_INTEGER := DBMS_LOB.SESSION); |
各个参数语法如下:
Parameter | Description |
---|---|
lob_loc | Receives the locator to the LOB. |
cache | Specifies whether the LOB should be read into the buffer cache. |
dur | Controls the duration of the LOB. The dur argument can be one of these two named constants:
DBMS_LOB.SESSION DBMS_LOB.CALL |
* 隐式创建
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://yuechaotian.cublog.cn'; temp_blob := HEXTORAW('7A'); END; |
2. 释放
使用系统过程 DBMS_LOB.FREETEMPORARY 释放 Temporary LOB。
PROCEDURE DBMS_LOB.FREETEMPORARY ( lob_loc IN OUT NOCOPY [ BLOB | CLOB CHARACTER SET ANY_CS ]); |
例如:
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.exploringthenorth.com/alger/alger.html'; temp_blob := HEXTORAW('7A');
DBMS_LOB.FREETEMPORARY(temp_clob);
DBMS_LOB.FREETEMPORARY(temp_blob); END; |
在 PL/SQL 中,若已被释放掉的 Temporary LOB 指针被赋值给另一个 LOB 指针,则这个指针也被释放:
SQL> DECLARE 2 temp_clob CLOB; 3 temp_clob2 CLOB; 4 BEGIN 5 temp_clob := 'http://yuechaotian.cublog.cn'; 6 temp_clob2 := 'http://yuexingtian.cublog.cn'; 7 8 dbms_output.put_line(temp_clob); 9 dbms_output.put_line(temp_clob2); 10 11 DBMS_LOB.FREETEMPORARY(temp_clob); 12 13 -- temp_clob2 is freed 14 temp_clob2 := temp_clob; 15 dbms_output.put_line(temp_clob2); 16 END; 17 / http://yuechaotian.cublog.cn http://yuexingtian.cublog.cn DECLARE * ERROR 位于第 1 行: ORA-22275: 指定的 LOB 定位器无效 |
在 PL/SQL 中,越过该 Temporary LOB 的生存期后,它自动被释放。
3. 检查 LOB 是否为 Temporary
系统函数 DBMS_LOB.ISTEMPORARY 可以判断一个 LOB 指针是否指向 Temporary LOB 数据。
DBMS_LOB.ISTEMPORARY ( lob_loc IN [ BLOB | CLOB CHARACTER SET ANY_CS ]) RETURN INTEGER; |
返回 1 表示入参为 Temporary LOB 指针;返回 0 表示入参是 persistent LOB 指针:
SQL> DECLARE
2 temp_clob CLOB; 3 n_is_temporary number(1); 4 BEGIN 5 temp_clob := 'http://yuechaotian.cublog.cn'; 6 7 n_is_temporary := dbms_lob.istemporary(temp_clob); 8 dbms_output.put_line('n_is_temporary :' || n_is_temporary); 9 10 DBMS_LOB.FREETEMPORARY(temp_clob); 11 END; 12 / n_is_temporary :1
PL/SQL 过程已成功完成。
|
4. 管理 Temporary LOB
和 persistent LOB 不同,Temporary LOB 不支持事务管理、一致性读取、回滚等等,所以你应该注意以下几点:
* 当处理 Temporary LOB 发生错误时,你必须释放该 LOB,然后重新进行该处理;
* 由于不支持一致性读取和回滚,所以你不能将多个 LOB 指针都指向同一个 Temporary LOB 数据;
* 若一个用户想要修改一个 Temporary LOB 数据,但该数据与另一个 LOB 指针关联,则会发生该 Temporary LOB 数据的拷贝(deep copy)。那么指向该 LOB 数据的其它指针将会看到不同的数据。为了降低 deep copy,当将 Temporary LOB 作为参数传递时,使用 NOCOPY 线索;
* 通过调用 DBMS_LOB.COPY 过程,可以将 Temporary LOB 数据持久化到数据库中;
* 在一个会话中,Temporary LOB 指针是唯一的。不能将一个指针从一个会话传递到另一个会话,使得相关联的 LOB 数据在另一个会话中可用。
从 Oracle9i Database Release 1 开始,可以通过视图 v$temporary_lobs 来查看每个会话中有多少被缓存的和未被缓存的 LOBs。还可以通过数据字典 dba_segments 来查看每个会话中 LOB 占用的空间。