Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1705815
  • 博文数量: 136
  • 博客积分: 10021
  • 博客等级: 上将
  • 技术积分: 3261
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-22 11:26
文章分类

全部博文(136)

文章存档

2010年(1)

2009年(26)

2008年(109)

我的朋友

分类: Oracle

2008-06-06 16:43:41

前面我们提到过 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

Specifies that the temporary LOB created should be cleaned up (memory freed) at the end of the session. This is the default.


DBMS_LOB.CALL

Specifies that the temporary LOB created should be cleaned up (memory freed) at the end of the current program call in which the LOB was created.


* 隐式创建
 
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 :=' ';
   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 占用的空间。
阅读(2783) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~