普通的Select 语句只能显示该clob字段的定位器,不能显示CLOB的内容,应为以前做过类似的操作,使用PB,配置好相关的ODBC,可以直接将结果查询出来,然后save as memo_1.txt就可以了,这似乎对我们这里的这个需求比较适合,因为记录数量比较少,要的也比较紧急。
但是似乎不能对CLOB这种类型的操作完全体现出来,对CLOB字段的操作ORACL提供了多种使用和维护LOB的方式,如使用PL/SQL DBMS_LOB包、调用OCI(Oracle Call Interface)、使用Proc * C/C++、使用JDBC等,这其中一种比较简单有效的方式实际是PL/SQL dbms_lob的包,DBMS_LOB包中提供的所有函数和过程都以LOB定位器作为参数。
DBMS_LOB中有如下几个重要的过程:
APPEND() 将源LOB中的内容加到目的LOB中
COPY() 从源LOB中复制数据到目的LOB
ERASE() 删除LOB中全部或部分内容
TRIM() 将LOB值减少到指定的长度
WRITE() 向LOB 中写入数据
COMPARE() 比较两个同种数据类型的LOB的部分或全部值是否相同
GETLENGTH() 获取LOB的长度
READ() 从LOB中读出数据
其中最常用的可能是读和写了,
DECLARE
lobloc CLOB;
buffer VARCHAR2(2000);
amount NUMBER := 20;
offset NUMBER := 1;
BEGIN
–初始化要写入的数据
buffer := ‘This is a writing example’;
amount := length(buffer);
Select document INTO lobloc — 获取定位器并锁定行
FROM view_sites_info
Where site_id = 100 FOR Update;
dbms_lob.write(lobloc,amount,1,buffer);
COMMIT;
END;
/
需要特别指出的是:
1. 在调用写过程前一定要使用Select语句检索到定位器且用 FOR Update 子句锁定行,否则不能更新LOB;
2. 写过程从offset指定的位置开始,向LOB中写入长度为amount的数据,原LOB中在这个范围内的任何数据都将被覆盖。
3. 缓冲区的最大容量为32K字节,因此在写入大量数据时需多次调用该过程。
下面的代码演示了如何使用该过程读取LOB字段中的数据:
DECLARE
lobloc CLOB;
buffer VARCHAR2(2000);
amount NUMBER := 2;
offset NUMBER := 6;
BEGIN
Select document INTO lobloc –获取定位器
FROM lob_store
Where lob_id = 100;
dbms_lob.read(lobloc,amount,offset,buffer);–读取数据到缓冲区
dbms_output.put_line(buffer);–显示缓冲区中的数据
COMMIT;
END;
/
lob segment采用了自己特殊的一致性读的实现,不是使用undo tablespace来保留前映象,而是当发生update时在lob segment内分配一个chunk去插入一条新的记录。这样的话,如果一条记录修改了多次,那么它就存在多个版本,对于很大的lob对象来说,这是十分浪费空间的。所以oracle需要有一个办法来控制这个保留前映象的空间的大小,pctversion就是为了实现这个功能的。pctversion是一个百分比的值,就是当前所有lob空间中用来存放前映象的百分比,如果前映象的空间大于pctversion了,那么oracle将会重用这些前映象空间而不去扩展。
|
|