PostRank

2009/05/13

LogExplore操作手册

摘自:網路

  介绍

  Log Explorer主要用于对MSSQLServer的事物分析和数据恢复。你可以浏览日志、导出数据、恢复被修改或者删除的数据(包括执行过 update,delete,drop和truncate语句的表格)。一旦由于系统故障或者人为因素导致数据丢失,它能够提供在线快速的数据恢复,最大程度上保证恢复期间的其他事物不间断执行。

  他可以支持SQLServer7.0和SQLServer2000,提取标准数据库的日志文件或者备份文件中的信息。

  其中提供两个强大的工具:日志分析浏览,对象恢复。具体功能如下:

  l     日志文件浏览

  l     数据库变更审查

  l     计划和授权变更审查

  l     将日志记录导出到文件或者数据库表

  l     实时监控数据库事物

  l     计算并统计负荷

  l     通过有选择性的取消或者重做事物来恢复数据

  l     恢复被截断或者删除表中的数据

  l     运行SQL脚本

  产品

  LogExplore包含两部分

  l     客户端软件

  l     服务器代理

  服务器端代理是保存在SQLServer主机中的一个只读存储过程,他的作用是接受客户端请求,读取在线事物日志块并通过网络传给客户端软件,由客户端软件来读取这些原始的数据块来完成Log Explore所提供的所有功能。

  他依赖来的网络协议包括:

  l     Named Pipe:局域网中适用

  l     Tcp/Ip:广域网中适用

  数据库相关介绍

  事物日志(Transaction Log)

  SQLServer的每个数据库都包含事物日志,它以文件的形式存储,可以记录数据库的任何变化。发生故障时SQLServer就是通过它来保证数据的完整性。

  操作(Operation)

  操作是数据库中定义的"原子行为",每个操作都在日志文件中保存为一条记录。它可以是用户直接输入的SQL语句,比如标准的insert命令,日志文件中便会记录一条操作代码来标志这个insert操作。

  事物(Transaction)

  事物是一系列操作组成的序列。他可以理解为直观的不可分割的一笔业务,可以执行成功或者失败。典型的事物比如由应用程序发出的具有开启-提交功能的一组SQL语句。不同的事物靠事物Id号(transaction ID)来区分,具有相同ID的事物记录的日志也相同。

  在线事物日志(Online Transaction Log)

  在线事物日志是指当前活动数据库所用的日志。可以通过如下命令来确定其对应文件

  Select * from SYSFILES

  他的文件后缀名一般是.LDF

  离线事物日志(Offline Transaction Log)

  离线事物日志是指非活动数据库所用的日志。当其数据库处于关闭(ShutDown)才状态下可以进行复制备份操作。他的结果同在线事物日志完全相同。

  备份文件

  备份文件是保存食物日志备份的文件,通常管理员通过运行SQL语句或者企业管理器来生成该文件。备份文件的内部结构和事物日志不同,他采用称为MTF的格式来保存数据。一个备份文件可以包含一个日志的多组备份,甚至包括多个数据库的混合备份.

  设置为自动收缩

  企业管理器--服务器--右键数据库--属性--选项--选择"自动收缩"

  强烈要求该项不要选中.否则SQLServer将已循环的方式来覆盖先前的日志记录,将会导致LogExplore无法恢复错误.

  数据恢复介绍

  LogExplore允许你恢复应为误操作或者程序错误而导致的数据丢失或者更改.比如执行updateDelete语句时丢失了where子句,或者错误使用了Dts功能.

  LogExplore不支持直接修改数据库.他可以生成事物的逆操作脚本.

  如果log是delete table where ...的话,生成的文件代码就是insert table ....

  你可以通过SQL查询分析器,或者LogExplore的Run SQL Script功能来执行生成脚本.

  关于Undo

  Undo功能可以逆操作一组指定的用户事物。包括insert,delete和update,其局限性如下:

  l     事物类别:LogExplore只能undo用户事物。用户事物是指在用户表上定义的事物,不支持系统表的更新恢复。同时,他也不支持计划变更的回滚。

  l     Blob类型:包括text,ntext,image类型。LogExplore只支持这些类型的insert和delete恢复,不支持update语句恢复。

  关于redo

  Redo功能可以再次运行一组指定事物。它可以在以下情况中用到:

  丢失数据库而且没有任何备份文件。

  l     如果原始日志文件没有丢失可以通过Redo来实现恢复。

  l     通过完整备份文件来把数据库恢复到某指定时间点,再通过redo功能完整恢复。它可以重放Create Table和Create Index命令,来重新生成被删掉的表,同时也受blob字段的限制。

  拯救Dropped/Truncate命令导致的数据丢失

  执行Drop Table和Truncate Table命令虽然会被SQLServer记录到日志文件中,但是并不记录被删除的数据。你可以使用LogExplore提供的功能来恢复这些数据。 LogExplore提供两种机制来恢复被Drop或者Truncate的数据。

  1、如果你有备份文件可以直接通过备份文件恢复。

  2、通过LogExplore提供的方法来恢复。

  当执行如上命令时,SQLServer会将保存数据的页面放入空闲页面列表中。如果此页没有被再次使用则将一直保存原始数据。恢复时,LogExplore将从空闲页面列表中搜寻没有被再次使用的页面,然后生成一个SQL脚本来从这些页面重组原始数据。LogExplore可以确定被删掉的原始数据行,并在完成时显示原始行数和实际恢复的行数,由此可以断定是否全部恢复。

  SQL逆操作

  1、Insert--Delete

  2、Delete--Insert

  3、Update

  注意:如果你选中了'Do not restore column values that have been changed by subsequent modifications'项,只对事物1逆转将不会产生任何结果。

  自增序列(IDENTITY Property)

  如果被删除数据与有IDENTITY Property属性,恢复时LogExlpore可以通过SET IDENTITY_INSERT ON 命令来对插入的数据设置Identity属性,并保留原数据不变,也可以对该列付与新值。

  数据导出:

  浏览日志时可将数据导出为xml,html,或者其他有分隔符的文件.也可以指定到一个SQL的表中.

  操作指南

  Attaching to a Log:在所有操作之前必须添加日志文件,

  l     可以用普通的SQL登录方式添加在线日志(Online Log),

  l     直接选择LDF文件来添加离线日志(OffLine Log)

  l     添加备份文件

  登录之后界

LogExplore的一个详细操作手册

  功能介绍:

  1、 Log Summary

  日志文件的概要信息。

  2、 Load Analysis

  列出指定时间范围内的一些事物,用户和表载入的概要信息。

  3、 Filter Log Record

  日志过滤设置。支持过滤条件包括:时间、操作类型、表、用户、SPID、搜索深度、Dropped表项以及登录设置和应用程序设置

  4、Browse

  日志浏览,核心模块。

LogExplore的一个详细操作手册

  1、 View Log功能:

  列表如图,可以用TransID来区分事物并用不同颜色标识。工具栏的按钮是一些基本查询操作。鼠标右键弹出菜单中有Undo Transaction和UndoOperation可以恢复黑色箭头选中的事物或者操作项。

  Real-Time Monitor:

  实时监控事物日志,通过轮询来实现。可以暂停或者停止监控,可以更改轮询周期。

  相关DML语言和DDL语言可以在Row Revision History、Row Transaction History以及View DDL Commands来查询。

  2、 Export Log Report

  包括Export To SQL和Export To File,根据向导即可完成。

  3、 其余菜单:Undo,Redo,Salvage Dropped/Truncated data,Restore 以及Run SQL Script前面已经叙述过,可以根据其向导完成。

  log explorer使用的几个问题

  1)对数据库做了完全 差异 和日志备份

  备份时选用了删除事务日志中不活动的条目

  再用Log explorer打试图看日志时

  提示No log recorders found that match the filter,would you like to view unfiltered data

  选择yes 就看不到刚才的记录了

  如果不选用了删除事务日志中不活动的条目

  再用Log explorer打试图看日志时,就能看到原来的日志

  2)修改了其中一个表中的部分数据,此时用Log explorer看日志,可以作日志恢复

  3)然后恢复备份,(注意:恢复是断开log explorer与数据库的连接,或连接到其他数据上,

  否则会出现数据库正在使用无法恢复)

  恢复完后,再打开log explorer 提示No log recorders found that match the filter,would you like to view unfiltered data

  选择yes 就看不到刚才在2中修改的日志记录,所以无法做恢复.

  3)

  不要用SQL的备份功能备份,搞不好你的日志就破坏了.

  正确的备份方法是:

  停止SQL服务,复制数据文件及日志文件进行文件备份.

  然后启动SQL服务,用log explorer恢复数据

  LogExplore

  下载地址: http://js.fixdown.com/soft/8324.asp?free=gdcnc-down1

  介绍

  Log Explorer主要用于对MSSQLServer的事物分析和数据恢复。你可以浏览日志、导出数据、恢复被修改或者删除的数据(包括执行过 update,delete,drop和truncate语句的表格)。一旦由于系统故障或者人为因素导致数据丢失,它能够提供在线快速的数据恢复,最大程度上保证恢复期间的其他事物不间断执行。

  他可以支持SQLServer7.0和SQLServer2000,提取标准数据库的日志文件或者备份文件中的信息。

  其中提供两个强大的工具:日志分析浏览,对象恢复。具体功能如下:

  l     日志文件浏览

  l     数据库变更审查

  l     计划和授权变更审查

  l     将日志记录导出到文件或者数据库表

  l     实时监控数据库事物

  l     计算并统计负荷

  l     通过有选择性的取消或者重做事物来恢复数据

  l     恢复被截断或者删除表中的数据

  l     运行SQL脚本

  产品

  LogExplore包含两部分

  l     客户端软件

  l     服务器代理

  服务器端代理是保存在SQLServer主机中的一个只读存储过程,他的作用是接受客户端请求,读取在线事物日志块并通过网络传给客户端软件,由客户端软件来读取这些原始的数据块来完成Log Explore所提供的所有功能。

  他依赖来的网络协议包括:

  l     Named Pipe:局域网中适用

  l     Tcp/Ip:广域网中适用

  数据库相关介绍

  事物日志(Transaction Log)

  SQLServer的每个数据库都包含事物日志,它以文件的形式存储,可以记录数据库的任何变化。发生故障时SQLServer就是通过它来保证数据的完整性。

  操作(Operation)

  操作是数据库中定义的"原子行为",每个操作都在日志文件中保存为一条记录。它可以是用户直接输入的SQL语句,比如标准的insert命令,日志文件中便会记录一条操作代码来标志这个insert操作。

  事物(Transaction)

  事物是一系列操作组成的序列。他可以理解为直观的不可分割的一笔业务,可以执行成功或者失败。典型的事物比如由应用程序发出的具有开启-提交功能的一组SQL语句。不同的事物靠事物Id号(transaction ID)来区分,具有相同ID的事物记录的日志也相同。

  在线事物日志(Online Transaction Log)

  在线事物日志是指当前活动数据库所用的日志。可以通过如下命令来确定其对应文件

  Select * from SYSFILES

  他的文件后缀名一般是.LDF

  离线事物日志(Offline Transaction Log)

  离线事物日志是指非活动数据库所用的日志。当其数据库处于关闭(ShutDown)才状态下可以进行复制备份操作。他的结果同在线事物日志完全相同。

  备份文件

  备份文件是保存食物日志备份的文件,通常管理员通过运行SQL语句或者企业管理器来生成该文件。备份文件的内部结构和事物日志不同,他采用称为MTF的格式来保存数据。一个备份文件可以包含一个日志的多组备份,甚至包括多个数据库的混合备份.

  设置为自动收缩

  企业管理器--服务器--右键数据库--属性--选项--选择"自动收缩"

  强烈要求该项不要选中.否则SQLServer将已循环的方式来覆盖先前的日志记录,将会导致LogExplore无法恢复错误.

  数据恢复介绍

  LogExplore允许你恢复应为误操作或者程序错误而导致的数据丢失或者更改.比如执行updateDelete语句时丢失了where子句,或者错误使用了Dts功能.

  LogExplore不支持直接修改数据库.他可以生成事物的逆操作脚本.

  如果log是delete table where ...的话,生成的文件代码就是insert table ....

  你可以通过SQL查询分析器,或者LogExplore的Run SQL Script功能来执行生成脚本.

  关于Undo

  Undo功能可以逆操作一组指定的用户事物。包括insert,delete和update,其局限性如下:

  l     事物类别:LogExplore只能undo用户事物。用户事物是指在用户表上定义的事物,不支持系统表的更新恢复。同时,他也不支持计划变更的回滚。

  l     Blob类型:包括text,ntext,image类型。LogExplore只支持这些类型的insert和delete恢复,不支持update语句恢复。

  关于redo

  Redo功能可以再次运行一组指定事物。它可以在以下情况中用到:

  丢失数据库而且没有任何备份文件。

  l     如果原始日志文件没有丢失可以通过Redo来实现恢复。

  l     通过完整备份文件来把数据库恢复到某指定时间点,再通过redo功能完整恢复。它可以重放Create Table和Create Index命令,来重新生成被删掉的表,同时也受blob字段的限制。

  拯救Dropped/Truncate命令导致的数据丢失

  执行Drop Table和Truncate Table命令虽然会被SQLServer记录到日志文件中,但是并不记录被删除的数据。你可以使用LogExplore提供的功能来恢复这些数据。 LogExplore提供两种机制来恢复被Drop或者Truncate的数据。

  1、如果你有备份文件可以直接通过备份文件恢复。

  2、通过LogExplore提供的方法来恢复。

  当执行如上命令时,SQLServer会将保存数据的页面放入空闲页面列表中。如果此页没有被再次使用则将一直保存原始数据。恢复时,LogExplore将从空闲页面列表中搜寻没有被再次使用的页面,然后生成一个SQL脚本来从这些页面重组原始数据。LogExplore可以确定被删掉的原始数据行,并在完成时显示原始行数和实际恢复的行数,由此可以断定是否全部恢复。

  SQL逆操作

  1、Insert--Delete

  2、Delete--Insert

  3、Update

  注意:如果你选中了'Do not restore column values that have been changed by subsequent modifications'项,只对事物1逆转将不会产生任何结果。

  自增序列(IDENTITY Property)

  如果被删除数据与有IDENTITY Property属性,恢复时LogExlpore可以通过SET IDENTITY_INSERT ON 命令来对插入的数据设置Identity属性,并保留原数据不变,也可以对该列付与新值。

  数据导出:

  浏览日志时可将数据导出为xml,html,或者其他有分隔符的文件.也可以指定到一个SQL的表中.

  操作指南

  Attaching to a Log:在所有操作之前必须添加日志文件,

  l     可以用普通的SQL登录方式添加在线日志(Online Log),

  l     直接选择LDF文件来添加离线日志(OffLine Log)

  l     添加备份文件

  登录之后界面

Column1 Column2 
A B

  事物1

Column1 Column2 
X B

  事物2

Column1 Column2 
Z T

  你可以只对事物1做逆操作

Column1 Column2 
A T

Column1 Column2 
A B

  事物1

Column1 Column2 
X B

  事物2

Column1 Column2 
Z T

  你可以只对事物1做逆操作

Column1 Column2 
A T

来源:csdn 作者:贾涛 责编:豆豆技术应用

Oracle內建包DBMS_LOB使用說明

摘自:網路

Oracle DBMS_LOB
Version 11.1
General Information
Source {ORACLE_HOME}/rdbms/admin/dbmslob.sql
First Available 8.0

Constants
Name Data Type Value
call PLS_INTEGER 12
default_csid INTEGER 0
default_lang_ctx INTEGER 0
file_readonly BINARY_INTEGER 0
lob_readonly BINARY_INTEGER 0
lob_readwrite BINARY_INTEGER 1
lobmaxsize INTEGER 18446744073709551615
no_warning INTEGER 0
session PLS_INTEGER 10
transaction PLS_INTEGER 11
warn_inconvertible_char INTEGER 1
Option Types
opt_compress PLS_INTEGER 1
opt_encrypt PLS_INTEGER 2
opt_deduplicate PLS_INTEGER 4
Option Values
compress_off PLS_INTEGER 0
compress_on PLS_INTEGER 1
encrypt_off PLS_INTEGER 0
encrypt_on PLS_INTEGER 2
deduplicate_off PLS_INTEGER 0
deduplicate_on PLS_INTEGER 4

Data Types
TYPE blob_deduplicate_region IS RECORD (
lob_offset INTEGER,
len INTEGER,
primary_lob BLOB,
primary_lob_offset NUMBER,
mime_type VARCHAR2(80));

TYPE blob_deduplicate_region_tab
IS TABLE OF blob_deduplicate_region
INDEX BY PLS_INTEGER;

TYPE clob_deduplicate_region IS RECORD (
lob_offset INTEGER,
len INTEGER,
primary_lob CLOB,
primary_lob_offset NUMBER,
mime_type VARCHAR2(80));

TYPE clob_deduplicate_region_tab
IS TABLE OF clob_deduplicate_region
INDEX BY PLS_INTEGER;

Dependencies
SELECT name
FROM dba_dependencies
WHERE referenced_name = 'DBMS_LOB'
UNION
SELECT referenced_name
FROM dba_dependencies
WHERE name = 'DBMS_LOB';

Exceptions
Error Code Reason
ORA-21560 The argument is expecting a non-null, valid value but the argument value passed in is null, invalid, or out of range
ORA-22285 The directory leading to the file does not exist
ORA-22286 user does not have the necessary access privileges on the directory alias and/or file
ORA-22287 directory alias is not valid
ORA-22288 file operation failed
ORA-22288 The file is not open for the required operation
ORA-22290 open files has reached the maximum limit
ORA-22925 operation exceeds maximum lob size
Object Privileges Execute is granted to PUBLIC
APPEND

Appends the contents of a source internal LOB to a destination LOB

Overload 1
dbms_lob.append(
dest_lob IN OUT NOCOPY BLOB,
src_lob IN BLOB);
CREATE OR REPLACE PROCEDURE Example_1a IS
dest_lob BLOB;
src_lob BLOB;
BEGIN
-- get the LOB locators
-- note that the FOR UPDATE clause locks the row
SELECT b_lob INTO dest_lob
FROM lob_table
WHERE key_value = 12
FOR UPDATE;

SELECT b_lob INTO src_lob
FROM lob_table
WHERE key_value = 21;

dbms_lob.append(dest_lob, src_lob);
COMMIT;
END;

Overload 2
dbms_lob.append(
dest_lob IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
src_lob IN CLOB CHARACTER SET dest_lob%CHARSET);
CREATE OR REPLACE PROCEDURE Example_1b IS
dest_lob, src_lob BLOB;
BEGIN
-- get the LOB locators
SELECT b_lob INTO dest_lob
FROM lob_table
WHERE key_value = 12
FOR UPDATE;

SELECT b_lob INTO src_lob
FROM lob_table
WHERE key_value = 12;

dbms_lob.append(dest_lob, src_lob);
COMMIT;
END;
/
CLOSE
Closes a previously opened internal or external LOB

Overload 1
dbms_lob.close(lob_loc IN OUT NOCOPY BLOB);
TBD
Overload 2 dbms_lob.close(lob_loc IN OUT NOCOPY CLOB CHARACTER SET ANY_CS);
See CREATETEMPORARY demo
Overload 3 dbms_lob.close(file_loc IN OUT NOCOPY BFILE);
TBD
COMPARE

Compares two entire LOBs or parts of two LOBs

Overload 1
dbms_lob.compare(
lob_1 IN BLOB,
lob_2 IN BLOB,
amount IN INTEGER := 18446744073709551615,
offset_1 IN INTEGER := 1,
offset_2 IN INTEGER := 1)
RETURN INTEGER;
TBD

Overload 2
dbms_lob.compare(
lob_1 IN CLOB CHARACTER SET ANY_CS,
lob_2 IN CLOB CHARACTER SET lob_1%CHARSET,
amount IN INTEGER := 18446744073709551615,
offset_1 IN INTEGER := 1,
offset_2 IN INTEGER := 1)
RETURN INTEGER;
TBD

Overload 3
dbms_lob.compare(
file_1 IN BFILE,
file_2 IN BFILE,
amount IN INTEGER,
offset_1 IN INTEGER := 1,
offset_2 IN INTEGER := 1)
RETURN INTEGER;
TBD
CONVERTOBLOB

Reads character data from a source CLOB or NCLOB instance, converts the character data to the specified character, writes the converted data to a destination BLOB instance in binary format, and returns the new offsets
dbms_lob.convertToBlob(
dest_lob IN OUT NOCOPY BLOB,
src_clob IN CLOB CHARACTER SET ANY_CS,
amount IN INTEGER,
dest_offset IN OUT INTEGER,
src_offset IN OUT INTEGER,
blob_csid IN NUMBER,
lang_context IN OUT INTEGER,
warning OUT INTEGER);
TBD
CONVERTOCLOB

Takes a source BLOB instance, converts the binary data in the source instance to character data using the specified character, writes the character data to a destination CLOB or NCLOB instance, and returns the new offsets
dbms_lob.convertToClob(
dest_lob IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
src_blob IN BLOB,
amount IN INTEGER,
dest_offset IN OUT INTEGER,
src_offset IN OUT INTEGER,
blob_csid IN NUMBER,
lang_context IN OUT INTEGER,
warning OUT INTEGER);
TBD
COPY

Copies all, or part, of the source LOB to the destination LOB

Overload 1
dbms_lob.copy(
dest_lob IN OUT NOCOPY BLOB,
src_lob IN BLOB,
amount IN INTEGER,
dest_offset IN INTEGER := 1,
src_offset IN INTEGER := 1);
TBD

Overload 2
dbms_lob.copy(
dest_lob IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
src_lob IN CLOB CHARACTER SET dest_lob%CHARSET,
amount IN INTEGER,
dest_offset IN INTEGER := 1,
src_offset IN INTEGER := 1);
TBD
CREATETEMPORARY

Creates a temporary BLOB or CLOB and its corresponding index in the user's default temporary tablespace

Overload 1
dbms_lob.createtemporary(
lob_loc IN OUT NOCOPY BLOB,
cache IN BOOLEAN,
dur IN PLS_INTEGER := 10);
DECLARE
clobvar CLOB := EMPTY_CLOB;
len BINARY_INTEGER;
x VARCHAR2(80);
BEGIN
dbms_lob.createtemporary(clobvar, TRUE);
dbms_lob.open(clobvar, dbms_lob.lob_readwrite);
x := 'before line break' || CHR(10) || 'after line break';
len := length(x);
dbms_lob.writeappend(clobvar, len, x);
dbms_lob.close(clobvar);
END;
/

Overload 2
dbms_lob.createtemporary(
lob_loc IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
cache IN BOOLEAN,
dur IN PLS_INTEGER := 10);
TBD
EMPTY_BLOB

Null BLOB
dbms_lob.empty_blob();
CREATE TABLE ebdemo (
fid NUMBER(3),
iclob BLOB);

INSERT INTO ebdemo
(fid, iblob)
VALUES
(1, EMPTY_BLOB());
EMPTY_CLOB

Null CLOB
dbms_lob.empty_clob();
CREATE TABLE ecdemo (
fid NUMBER(3),
iclob CLOB);

INSERT INTO ecdemo
(fid, iclob)
VALUES
(1, EMPTY_CLOB());

ERASE
Erases all or part of a LOB

Overload 1
dbms_lob.erase(
lob_loc IN OUT NOCOPY BLOB,
amount IN OUT NOCOPY INTEGER,
offset IN INTEGER := 1);
TBD
Overload 2 dbms_lob.erase(
lob_loc IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
amount IN OUT NOCOPY INTEGER,
offset IN INTEGER := 1);
TBD
FILECLOSE
Closes a file opened with dbms_lob.file_open dbms_lob.fileclose(file_loc IN OUT NOCOPY BFILE);
exec dbms_lob.fileclose(src_file);
FILECLOSEALL
Closes all files opened with dbms_lob.file_open dbms_lob.filecloseall;
exec dbms_lob.fileclose;
FILEEXISTS
Determine whether a file exists dbms_lob.fileexists(file_loc IN BFILE) RETURN INTEGER;
TBD
FILEGETNAME
Returns the source filename and directory given a BFILE dbms_lob.filegetname(
file_loc IN BFILE,
dir_alias OUT VARCHAR2,
filename OUT VARCHAR2);
TBD
FILEISOPEN
Checks if the file was opened using the input BFILE locators dbms_lob.fileisopen(file_loc IN BFILE) RETURN INTEGER;
TBD
FILEOPEN
Open a file for reading dbms_lob.fileopen(
file_loc IN OUT NOCOPY BFILE,
open_mode IN BINARY_INTEGER := file_readonly);
exec dbms_lob.fileopen(src_file, dbms_lob.file_readonly);
FRAGMENT_DELETE
Deletes the data at the given offset for the given length from the LOB

Overload 1
dbms_lob.fragment_delete(
lob_loc IN OUT NOCOPY
BLOB,
amount IN INTEGER,
offset IN INTEGER);
TBD
Overload 2 dbms_lob.fragment_delete(
lob_loc IN OUT NOCOPY
CLOB CHARACTER SET ANY_CS,
amount IN INTEGER,
offset IN INTEGER);
TBD
FRAGMENT_INSERT
Inserts the given data (limited to 32K) into the LOB at the given offset

Overload 1
dbms_lob.fragment_insert(
lob_loc IN OUT NOCOPY
BLOB,
amount IN INTEGER,
offset IN INTEGER,
buffer IN RAW);
TBD
Overload 2 dbms_lob.fragment_insert(
lob_loc IN OUT NOCOPY
CLOB CHARACTER SET ANY_CS,
amount IN INTEGER,
offset IN INTEGER,
buffer IN
VARCHAR2 CHARACTER SET lob_loc%CHARSET);
TBD
FRAGMENT_MOVE
Moves the amount of bytes (BLOB) or characters (CLOB/NCLOB) from the given offset to the new offset specified

Overload 1
dbms_lob.fragment_move(
lob_loc IN OUT NOCOPY
BLOB,
amount IN INTEGER,
src_offset IN INTEGER,
dest_offset IN INTEGER);
TBD
Overload 2 dbms_lob.fragment_move(
lob_loc IN OUT NOCOPY
CLOB CHARACTER SET ANY_CS,
amount IN INTEGER,
src_offset IN INTEGER,
dest_offset IN INTEGER);
TBD
FRAGMENT_REPLACE
Replaces the data at the given offset with the given data (not to exceed 32k)

Overload 1
dbms_lob.fragment_replace(
lob_loc IN OUT NOCOPY
BLOB,
old_amount IN INTEGER,
new_amount IN INTEGER,
offset IN INTEGER,
buffer IN RAW);
TBD
Overload 2 dbms_lob.fragment_replace(
lob_loc IN OUT NOCOPY
CLOB CHARACTER SET ANY_CS,
old_amount IN INTEGER,
new_amount IN INTEGER,
offset IN INTEGER,
buffer IN VARCHAR2
CHARACTER SET lob_loc%CHARSET);
TBD
FREETEMPORARY

Frees the temporary BLOB or CLOB in the default temporary tablespace

Overload 1
dbms_lob.freetemporary(lob_loc IN OUT NOCOPY BLOB);
conn pm/pm

desc print_media

SELECT ad_sourcetext
FROM print_media
WHERE product_id = 2056;

set long 100000

SELECT ad_sourcetext
FROM print_media
WHERE product_id = 2056;

set serveroutput on

DECLARE
clobvar CLOB;
BEGIN
SELECT ad_sourcetext
INTO clobvar
FROM print_media
WHERE product_id = 2056;

dbms_output.put_line('1: ' || clobvar);

dbms_lob.freetemporary(clobvar);

dbms_output.put_line('2: ' || clobvar);
END;
/
Overload 2 dbm_lob.freetemporary(
lob_loc IN OUT NOCOPY CLOB CHARACTER SET ANY_CS);
TBD
GETCHUNKSIZE
Returns the amount of space used in the LOB chunk to store the LOB value

Overload 1
dbms_lob.getchunksize(lob_loc IN BLOB) RETURN INTEGER;
TBD
Overload 2 dbms_lob.getchunksize(lob_loc IN CLOB CHARACTER SET ANY_CS)
RETURN INTEGER;
TBD
GETLENGTH

Gets the length of the LOB value


Overload 1
dbms_lob.getlength(lob_loc IN BLOB) RETURN INTEGER;
conn pm/pm

desc print_media

SELECT dbms_lob.getlength(ad_photo)
FROM print_media;

Overload 2
dbms_lob.getlength(lob_loc IN CLOB CHARACTER SET ANY_CS)
RETURN INTEGER;
conn pm/pm

desc print_media

SELECT dbms_lob.getlength(ad_sourcetext)
FROM print_media;

Overload 3
dbms_lob.getlength(file_loc IN BFILE) RETURN INTEGER;
DECLARE
src_file BFILE;
dst_file BLOB;
lgh_file BINARY_INTEGER;
BEGIN
src_file := bfilename('CTEMP', 'myfile.txt');
lgh_file := dbms_lob.getlength(src_file);
END;
/
GET_DEDUPLICATE_REGIONS (new in 11g)
Undocumented

Overload 1
dbms_lob.get_deduplicate_regions(
lob_loc IN
BLOB,
region_table IN OUT NOCOPY
BLOB_DEDUPLICATE_REGION_TAB);
TBD
Overload 2 dbms_lob.get_deduplicate_regions(
lob_loc IN
CLOB CHARACTER SET ANY_CS,
region_table IN OUT NOCOPY
CLOB_DEDUPLICATE_REGION_TAB);
TBD
GETOPTIONS

Obtains settings corresponding to the option_types field for a particular LOB


Overload 1
dbms_lob.getoptions(
lob_loc IN
BLOB,
option_types IN PLS_INTEGER)
RETURN PLS_INTEGER;
See SECUREFILES demo
Overload 2 dbms_lob.getoptions(
lob_loc IN
CLOB CHARACTER SET ANY_CS,
option_types IN PLS_INTEGER)
RETURN PLS_INTEGER;
TBD
GET_STORAGE_LIMIT
Returns the storage limit for LOBs in your database configuration

Overload 1
dbms_lob.get_storage_limit(
lob_loc IN CLOB CHARACTER SET ANY_CS) RETURN INTEGER;
conn pm/pm

desc print_media

SELECT dbms_lob.get_storage_limit(ad_sourcetext)
FROM print_media;
Overload 2 dbms_lob.get_storage_limit(lob_loc IN BLOB) RETURN INTEGER;
conn pm/pm

desc print_media

SELECT dbms_lob.get_storage_limit(ad_photo)
FROM print_media;
INSTR

Returns the matching position of the nth occurrence of the pattern in the LOB

Overload 1
dbms_lob.instr(
lob_loc IN BLOB,
pattern IN RAW,
offset IN INTEGER := 1,
nth IN INTEGER := 1) RETURN INTEGER;
TBD

Overload 2
dbms_lob.instr(
lob_loc IN CLOB CHARACTER SET ANY_CS,
pattern IN VARCHAR2 CHARACTER SET lob_loc%CHARSET,
offset IN INTEGER := 1,
nth IN INTEGER := 1) RETURN INTEGER;
conn pm/pm

SELECT dbms_lob.getlength(ad_sourcetext), dbms_lob.instr(ad_sourcetext, 'A')
FROM print_media;

SELECT dbms_lob.getlength(ad_sourcetext), dbms_lob.instr(ad_sourcetext, 'E')
FROM print_media;

Overload 3
dbms_lob.instr(
file_loc IN BFILE,
pattern IN RAW,
offset IN INTEGER := 1,
nth IN INTEGER := 1) RETURN INTEGER;
TBD
ISOPEN
Checks to see if the LOB was already opened using the input locator

Overload 1
dbms_lob.isopen(lob_loc IN BLOB) RETURN INTEGER;
TBD
Overload 2 dbms_lob.isopen(lob_loc IN CLOB CHARACTER SET ANY_CS)
RETURN INTEGER;
TBD
Overload 3 dbms_lob.isopen(file_loc IN BFILE) RETURN INTEGER;
TBD

ISSECUREFILE (new in 11g)
Returns TRUE is a LOB has been stored in an encrypted SECUREFILE

Overload 1
dbms_lob.issecurefile(lob_loc IN BLOB) RETURN BOOLEAN;
See SECUREFILES demo
Overload 2 dbms_lob.issecurefile(lob_loc IN CLOB CHARACTER SET ANY_CS)
RETURN BOOLEAN;
TBD
ISTEMPORARY
Checks if the locator is pointing to a temporary LOB

Overload 1
dbms_lob.istemporary(lob_loc IN BLOB) RETURN INTEGER;
TBD
Overload 2 dbms_lob.istemporary(lob_loc IN CLOB CHARACTER SET ANY_CS)
RETURN INTEGER;
TBD
LOADBLOBFROMFILE

Loads BFILE data into an internal BLOB
dbm_lob.loadblobfromfile(
dest_lob IN OUT NOCOPY BLOB,
src_bfile IN BFILE,
amount IN INTEGER,
dest_offset IN OUT INTEGER,
src_offset IN OUT INTEGER);
TBD
LOADCLOBFROMFILE

Loads BFILE data into an internal CLOB
dbm_lob.loadclobfromfile(
dest_lob IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
src_bfile IN BFILE,
amount IN INTEGER,
dest_offset IN OUT INTEGER,
src_offset IN OUT INTEGER,
bfile_csid IN NUMBER,
lang_context IN OUT INTEGER,
warning OUT INTEGER);
TBD
LOADFROMFILE
Loads BFILE data into an internal LOB

Overload 1
dbms_lob.loadfromfile(
dest_lob IN OUT NOCOPY BLOB,
src_lob IN BFILE,
amount IN INTEGER,
dest_offset IN INTEGER := 1,
src_offset IN INTEGER := 1);
exec dbms_lob.loadfromfile(dst_file, src_file, lgh_file);
Overload 2 dbms_lob.loadfromfile(
dest_lob IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
src_lob IN BFILE,
amount IN INTEGER,
dest_offset IN INTEGER := 1,
src_offset IN INTEGER := 1);
TBD
OPEN
Opens a LOB (internal, external, or temporary) in the indicated mode

Overload 1
dbms_lob.open(
lob_loc IN OUT NOCOPY BLOB,
open_mode IN BINARY_INTEGER);
TBD
Overload 2 dbms_lob.open(
lob_loc IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
open_mode IN BINARY_INTEGER);
See CREATETEMPORARY demo
Overload 3 dbms_lob.open(
file_loc IN OUT NOCOPY BFILE,
open_mode IN BINARY_INTEGER := file_readonly);
TBD
READ
Reads data from the LOB starting at the specified offset

Overload 1
dbms_lob.read(
lob_loc IN BLOB,
amount IN OUT NOCOPY INTEGER,
offset IN INTEGER,
buffer OUT RAW);
TBD
Overload 2 dbms_lob.read(
lob_loc IN CLOB CHARACTER SET ANY_CS,
amount IN OUT NOCOPY INTEGER,
offset IN INTEGER,
buffer OUT VARCHAR2 CHARACTER SET lob_loc%CHARSET);
TBD
Overload 3 dbms_lob.read(
file_loc IN BFILE,
amount IN OUT NOCOPY INTEGER,
offset IN INTEGER,
buffer OUT RAW);
TBD
SETOPTIONS

Enables CSCE features on a per-LOB basis, overriding the default LOB column settings

Overload 1
dbms_lob.setoptions(
lob_loc IN OUT NOCOPY
BLOB,
option_types IN PLS_INTEGER,
options IN PLS_INTEGER);

Option Types

opt_compress 1
opt_encrypt 2
opt_deduplicate 4

Options

compress_off 0
compress_on 1
encrypt_off 0
encrypt on 2
deduplicate_off 0
deduplicate_on 4
TBD
Overload 2 dbms_lob.setoptions(
lob_loc IN OUT NOCOPY
CLOB CHARACTER SET ANY_CS,
option_types IN PLS_INTEGER,
options IN PLS_INTEGER);
TBD
SUBSTR
Returns part of the LOB value starting at the specified offset

Overload 1
dbms_lob.substr(
lob_loc IN BLOB,
amount IN INTEGER := 32767,
offset IN INTEGER := 1)
RETURN RAW;
TBD
Overload 2 dbms_lob.substr(
lob_loc IN CLOB CHARACTER SET ANY_CS,
amount IN INTEGER := 32767,
offset IN INTEGER := 1)
RETURN VARCHAR2 CHARACTER SET lob_loc%CHARSET;
TBD
Overload 3 dbms_lob.substr(
file_loc IN BFILE,
amount IN INTEGER := 32767,
offset IN INTEGER := 1)
RETURN RAW;
TBD
TRIM
Trims the LOB value to the specified shorter length

Overload 1
dbms_lob.trim(lob_loc IN OUT NOCOPY BLOB, newlen IN INTEGER);
TBD
Overload 2 dbms_lob.trim(
lob_loc IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
newlen IN INTEGER);
TBD
WRITE
Writes data to the LOB from a specified offset

Overload 1
dbm_lob.write(
lob_loc IN OUT NOCOPY BLOB,
amount IN INTEGER,
offset IN INTEGER,
buffer IN RAW);
TBD
Overload 2 dbm_lob.write(
lob_loc IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
amount IN INTEGER,
offset IN INTEGER,
buffer IN VARCHAR2 CHARACTER SET lob_loc%CHARSET);
TBD
WRITEAPPEND
Writes a buffer to the end of a LOB

Overload 1
dbm_lob.writeappend(
lob_loc IN OUT NOCOPY BLOB,
amount IN INTEGER,
buffer IN RAW);
TBD

Overload 2
dbm_lob.writeappend(
lob_loc IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
amount IN INTEGER,
buffer IN VARCHAR2 CHARACTER SET lob_loc%CHARSET);
CREATE TABLE book (
bookid NUMBER(5),
title VARCHAR2(50),
description VARCHAR2(100));

INSERT INTO book
VALUES
(1, '11g Inovations', 'New Features in Oracle 11g');

CREATE TABLE author (
authorid NUMBER(5),
author_name VARCHAR2(60));

INSERT INTO author
VALUES
(1, 'Daniel Morgan');

CREATE TABLE book_author_ie (
bookid NUMBER(5),
authorid NUMBER(5));

INSERT INTO book_author_ie
SELECT bookid, authorid
FROM book, author;

CREATE OR REPLACE PROCEDURE xml_gen(cvar IN OUT NOCOPY CLOB) AS
CURSOR c IS
SELECT b.title, b.description, a.author_name
FROM book b, author a, book_author_ie ie
WHERE b.bookid = ie.bookid
AND a.authorid = ie.authorid;
BEGIN
FOR r IN c LOOP
dbms_lob.writeappend(cvar, 19, ''); <br /> <span style="color:#0000ff;">dbms_lob.writeappend</span>(cvar, length(r.title), r.title); <br /> <span style="color:#0000ff;">dbms_lob.writeappend</span>(cvar, 14, '');
dbms_lob.writeappend(cvar, length(r.description), r.description);
dbms_lob.writeappend(cvar, 27, '
');
dbms_lob.writeappend(cvar, length(r.author_name), r.author_name);
dbms_lob.writeappend(cvar, 21, '
');
END LOOP;
END xml_gen;
/

set serveroutput on

DECLARE
cvar CLOB := ' ';
BEGIN
xml_gen(cvar);
dbms_output.put_line(cvar);
END;
/
DBMS_LOB Demos

Blob Load Demo
/*
define the directory inside Oracle when logged on as SYS
create or replace directory ctemp as 'c:\temp\';

grant read on the directory to the Staging schema
grant read on directory ctemp to staging;
*/

-- the storage table for the image file

CREATE TABLE pdm (
dname VARCHAR2(30), -- directory name
sname VARCHAR2(30), -- subdirectory name
fname VARCHAR2(30), -- file name
iblob BLOB); -- image file
-- create the procedure to load the file
CREATE OR REPLACE PROCEDURE load_file (
pdname VARCHAR2,
psname VARCHAR2,
pfname VARCHAR2) IS

src_file BFILE;
dst_file BLOB;
lgh_file BINARY_INTEGER;
BEGIN
src_file := bfilename('CTEMP', pfname);

-- insert a NULL record to lock
INSERT INTO pdm
(dname, sname, fname, iblob)
VALUES
(pdname, psname, pfname, EMPTY_BLOB())
RETURNING iblob INTO dst_file;

-- lock record
SELECT iblob
INTO dst_file
FROM pdm
WHERE dname = pdname
AND sname = psname
AND fname = pfname
FOR UPDATE;

-- open the file
dbms_lob.fileopen(src_file, dbms_lob.file_readonly);

-- determine length
lgh_file := dbms_lob.getlength(src_file);

-- read the file
dbms_lob.loadfromfile(dst_file, src_file, lgh_file);

-- update the blob field
UPDATE pdm
SET iblob = dst_file
WHERE dname = pdname
AND sname = psname
AND fname = pfname;

-- close file
dbms_lob.fileclose(src_file);
END load_file;
/

Save BLOB to File Demo
How to save a BLOB to a file on disk in PL/SQL
From: Thomas Kyte

Use DBMS_LOB to read from the BLOB

You will need to create an external procedure to take binary data and write it to the operating system, the external procedure can be written in C. If it was CLOB data, you can use UTL_FILE to write it to the OS but UTL_FILE does not support the binary in a BLOB.

There are articles on MetaLink explaining how to do and it has a C program ready for compiling and the External Procedure stuff, i'd advise a visit.

Especially, look for Note:70110.1, Subject: WRITING BLOB/CLOB/BFILE CONTENTS TO A FILE USING EXTERNAL PROCEDURES

Here is the Oracle code cut and pasted from it. The outputstring procedure is the oracle procedure interface to the External procedure.

-------------------------------------

DECLARE
i1 BLOB;
len NUMBER;
my_vr RAW(10000);
i2 NUMBER;
i3 NUMBER := 10000;
BEGIN
-- get the blob locator
SELECT c2
INTO i1
FROM lob_tab
WHERE c1 = 2;

-- find the length of the blob column
len := dbms_lob.getlength(i1);
dbms_output.put_line('Column Length: ' || TO_CHAR(len));

-- Read 10000 bytes at a time
i2 := 1;
IF len < 10000 THEN
-- If the col length is <>
dbms_lob.read(i1,len,i2,my_vr);

outputstring('p:\bfiles\ravi.bmp',
rawtohex(my_vr),'wb',2*len);

-- You have to convert the data to rawtohex format.
-- Directly sending the buffer
-- data will not work
-- That is the reason why we are sending the length as
-- the double the size of the data read


dbms_output.put_line('Read ' || to_char(len) || 'Bytes');
ELSE
-- If the col length is > 10000
dbms_lob.read(i1,i3,i2,my_vr);

outputstring('p:\bfiles\ravi.bmp',
rawtohex(my_vr),'wb',2*i3);

dbms_output.put_line('Read ' || TO_CHAR(i3) || ' Bytes ');
END IF;

i2 := i2 + 10000;

WHILE (i2 < len )
LOOP
-- loop till entire data is fetched
dbms_lob.read(i1,i3,i2,my_vr);

dbms_output.put_line('Read ' || TO_CHAR(i3+i2-1) ||
' Bytes ');

outputstring('p:\bfiles\ravi.bmp',
rawtohex(my_vr),'ab',2*i3);

i2 := i2 + 10000 ;
END LOOP;
END;
/

Load from file demo
CREATE OR REPLACE PROCEDURE read_file IS
src_file BFILE := bfilename('DOCUMENT_DIR', 'image.gif');
dst_file BLOB;
lgh_file BINARY_INTEGER;
BEGIN
-- lock record
SELECT bin_data
INTO dst_file
FROM db_image
FOR update;

-- open the file
dbms_lob.fileopen(src_file, dbms_lob.file_readonly);

-- determine length
lgh_file := dbms_lob.getlength(src_file);

-- read the file
dbms_lob.loadfromfile(dst_file, src_file, lgh_file);

-- update the blob field
UPDATE db_image
SET bin_data = dst_file;
COMMIT;

-- close file
dbms_lob.fileclose(src_file);

EXCEPTION
WHEN access_error THEN

WHEN invalid_argval THEN

WHEN invalid_directory THEN

WHEN no_data_found THEN

WHEN noexist_directory THEN

WHEN nopriv_directory THEN

WHEN open_toomany THEN

WHEN operation_failed THEN

WHEN unopened_file THEN

WHEN others THEN

END read_file;
/

LOB Demo by Alberto Dell'Era
>> Actually, I have already done my own tests and it doesn't.
>> I can only retrieve 4000 as you already mentioned as
>> opposed to the 64000 we're used to, but I think that this
>> is a good trade off considering that we were doing almost
>> 5000 queries at a time.

Perhaps you could consider tuning the temp tablespace extent size to retain the ability to fetch 64000 bytes. Consider this test case (9.2.0.5, 8k block size):


CREATE TABLE don (x clob);


DECLARE
l_clob clob;
BEGIN
FOR i IN 1..10
LOOP
INSERT INTO don (x) VALUES (empty_clob())
RETURNING x INTO l_clob;

-- create a 400,000 bytes clob
FOR i IN 1..100
LOOP
dbms_lob.append(l_clob, rpad ('*',4000,'*'));
END LOOP;
END LOOP;
END;
/

CREATE TEMPORARY TABLESPACE don_1024
TEMPFILE 'c:\temp\don_1024.dbf' SIZE 10M
EXTENT MANAGEMENT LOCAL
UNIFORM SIZE 1024k;

CREATE TEMPORARY TABLESPACE don_512
TEMPFILE 'c:\temp\don_512.dbf' SIZE 10M
EXTENT MANAGEMENT LOCAL
UNIFORM SIZE 512k;

CREATE TEMPORARY TABLESPACE don_64
TEMPFILE 'c:\temp\don_64.dbf' SIZE 10M
EXTENT MANAGEMENT LOCAL
UNIFORM SIZE 64k;

SELECT tablespace_name, initial_extent
FROM dba_tablespaces
WHERE tablespace_name LIKE ('DON%');

TABLESPACE_NAME INITIAL_EXTENT
--------------- --------------
DON_1024 1048576
DON_512 524288
DON_64 65536

ALTER USER uwclass TEMPORARY TABLESPACE don_1024;

(You must exit and relog in to use the new temp tablespace)

SELECT SUBSTR (x, 1, 64000) PIECE
FROM don;

SELECT COUNT(*)
FROM gv$temporary_lobs
WHERE sid = (
SELECT sid FROM gv$mystat WHERE rownum = 1);

COUNT(*)
----------
1

(Note: Even if we fetched 10 rows, we have only 1 temp clob at the end).

SELECT tablespace, segtype, blocks*8*1024 USED_BYTES
FROM gv$tempseg_usage
WHERE username = user;

TABLESPACE SEGTYPE USED_BYTES
---------- ----------- ----------
DON_1024 LOB_DATA 1048576
DON_1024 LOB_INDEX 1048576

ALTER USER dellera TEMPORARY TABLESPACE don_512;

(logout then in again)

TABLESPACE SEGTYPE USED_BYTES
---------- ----------- ----------
DON_512 LOB_DATA 524288
DON_512 LOB_INDEX 524288

ALTER USER dellera TEMPORARY TABLESPACE don_64;

(logout then in again)

TABLESPACE SEGTYPE USED_BYTES
---------- ----------- ----------
DON_64 LOB_DATA 327680
DON_64 LOB_INDEX 65536


So by reducing the extent size we greatly reduce the space allocated to the temp lob_index. I don't know why the lob_data that should contain 64000 bytes stays to 327,680 for an extent size of 64K. Interestingly, if we select only 1 row:

SELECT SUBSTR(x, 1, 64000) PIECE
FROM don
WHERE rownum = 1;

TABLESPACE SEGTYPE USED_BYTES
---------- ----------- ----------
DON_64 LOB_DATA 196608
DON_64 LOB_INDEX 65536

I don't know the reason for this. Perhaps temporary LOBs have a different (bigger) CHUNKSIZE and/or PCTVERSION or perhaps they are updated versus being 'truncated' and then inserted for each row fetched?

Obviously, changing the extent size may adversely affect sort-to-disk and hash-join-to-disk, etc, operations - even if, by using an LMT temp tablespace, the impact may (stress on *may*) be immaterial.

Replaces All Code Occurrences Of A String With Another Within A CLOB
-- 1) clob src - the CLOB source to be replaced.
-- 2) replace str - the string to be replaced.
-- 3) replace with - the replacement string.

FUNCTION replaceClob (
srcClob IN CLOB,
replaceStr IN VARCHAR2,
replaceWith IN VARCHAR2)
RETURN CLOB IS

vBuffer VARCHAR2 (32767);
l_amount BINARY_INTEGER := 32767;
l_pos PLS_INTEGER := 1;
l_clob_len PLS_INTEGER;
newClob CLOB := EMPTY_CLOB;

BEGIN
-- initalize the new clob
dbms_lob.createtemporary(newClob,TRUE);

l_clob_len := dbms_lob.getlength(srcClob);

WHILE l_pos < l_clob_len
LOOP
dbms_lob.read(srcClob, l_amount, l_pos, vBuffer);

IF vBuffer IS NOT NULL THEN
-- replace the text
vBuffer := replace(vBuffer, replaceStr, replaceWith);
-- write it to the new clob
dbms_lob.writeappend(newClob, LENGTH(vBuffer), vBuffer);
END IF;
l_pos := l_pos + l_amount;
END LOOP;

RETURN newClob;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
/

2009/05/12

Oracle内建包UTL_FILE使用说明

摘自:網路

最近用到了Oracle的包UTL_FILE,网上却没找到关于它的函数,过程使用说明,虽然都不是很难的东西,但简单列出来,也能提高些效率。
于是有了这篇文。
以下翻译来自《Oracle Built-in Packages》的第六章,只翻译了部分,想了解的更详细,请参考原文。http://www.oreilly.com/catalog/oraclebip/chapter/ch06.html

FOPEN
IS_OPEN
GET_LINE
PUT
NEW_LINE
PUT_LINE
PUTF
FFLUSH
FCLOSE
FCLOSE_ALL

UTL_FILE.FOPEN 用法
FOPEN会打开指定文件并返回一个文件句柄用于操作文件。
所有PL/SQL版本: Oracle 8.0版及以上:
FUNCTION UTL_FILE.FOPEN ( FUNCTION UTL_FILE.FOPEN (
location IN VARCHAR2, location IN VARCHAR2,
filename IN VARCHAR2, filename IN VARCHAR2,
open_mode IN VARCHAR2) open_mode IN VARCHAR2,
RETURN file_type; max_linesize IN BINARY_INTEGER)
RETURN file_type;

参数

location
文件地址

filename
文件名

openmode
打开文件的模式(参见下面说明)

max_linesize
文件每行最大的字符数,包括换行符。最小为1,最大为32767

3种文件打开模式:
R 只读模式。一般配合UTL_FILE的GET_LINE来读文件。
W 写(替换)模式。文件的所有行会被删除。PUT, PUT_LINE, NEW_LINE, PUTF和FFLUSH都可使用
A 写(附加)模式。原文件的所有行会被保留。在最末尾行附加新行。PUT, PUT_LINE, NEW_LINE, PUTF和FFLUSH都可使用

打开文件时注意以下几点:
文件路径和文件名合起来必须表示操作系统中一个合法的文件。
文件路径必须存在并可访问;FOPEN并不会新建一个文件夹。
如果你想打开文件进行读操作,文件必须存在;如果你想打开文件进行写操作,文件不存在时,会新建一个文件。
如果你想打开文件进行附加操作,文件必须存在。A模式不同于W模式。文件不存在时,会抛出INVALID_OPERATION异常。

FOPEN 会抛出以下异常
UTL_FILE.INVALID_MODE
UTL_FILE.INVALID_OPERATION
UTL_FILE.INVALID_PATH
UTL_FILE.INVALID_MAXLINESIZE

UTL_FILE.IS_OPEN用法
如果文件句柄指定的文件已打开,返回TRUE,否则FALSE

FUNCTION UTL_FILE.IS_OPEN (file IN UTL_FILE.FILE_TYPE) RETURN BOOLEAN;

UTL_FILE只提供一个方法去读取数据:GET_LINE

UTL_FILE.GET_LINE用法
读取指定文件的一行到提供的缓存。
PROCEDURE UTL_FILE.GET_LINE
(file IN UTL_FILE.FILE_TYPE,
buffer OUT VARCHAR2);

file
由FOPEN返回的文件句柄

buffer
读取的一行数据的存放缓存

buffer必须足够大。否则,会抛出VALUE_ERROR 异常。行终止符不会被传进buffer。

异常
NO_DATA_FOUND
VALUE_ERROR
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.READ_ERROR


UTL_FILE.PUT用法
在当前行输出数据
PROCEDURE UTL_FILE.PUT
(file IN UTL_FILE.FILE_TYPE,
buffer OUT VARCHAR2);
file
由FOPEN返回的文件句柄
buffer
包含要写入文件的数据缓存;Oracle8.0.3及以上最大允许32kB,早期版本只有1023B

UTL_FILE.PUT输出数据时不会附加行终止符。

UTL_FILE.PUT会产生以下异常
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR

UTL_FILE.NEW_LINE
在当前位置输出新行或行终止符,必须使用NEW_LINE来结束当前行,或者使用PUT_LINE输出带有行终止符的完整行数据。

PROCEDURE UTL_FILE.NEW_LINE
(file IN UTL_FILE.FILE_TYPE,
lines IN NATURAL := 1);
file
由FOPEN返回的文件句柄
lines
要插入的行数

如果不指定lines参数,NEW_LINE会使用默认值1,在当前行尾换行。如果要插入一个空白行,可以使用以下语句:
UTL_FILE.NEW_LINE (my_file, 2);
如果lines参数为0或负数,什么都不会写入文件。

NEW_LINE会产生以下异常
VALUE_ERROR
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR
例子
如果要在UTL_FILE.PUT后立刻换行,可以如下例所示:
PROCEDURE add_line (file_in IN UTL_FILE.FILE_TYPE, line_in IN VARCHAR2)
IS
BEGIN
UTL_FILE.PUT (file_in, line_in);
UTL_FILE.NEW_LINE (file_in);
END;


UTL_FILE.PUT_LINE
输出一个字符串以及一个与系统有关的行终止符
PROCEDURE UTL_FILE.PUT_LINE
(file IN UTL_FILE.FILE_TYPE,
buffer IN VARCHAR2);
file
由FOPEN返回的文件句柄
buffer
包含要写入文件的数据缓存;Oracle8.0.3及以上最大允许32kB,早期版本只有1023B
在调用UTL_FILE.PUT_LINE前,必须先打开文件。
UTL_FILE.PUT_LINE会产生以下异常
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR

例子
这里利用UTL_FILE.PUT_LINE从表emp读取数据到文件:
PROCEDURE emp2file
IS
fileID UTL_FILE.FILE_TYPE;
BEGIN
fileID := UTL_FILE.FOPEN ('/tmp', 'emp.dat', 'W');

/* Quick and dirty construction here! */
FOR emprec IN (SELECT * FROM emp)
LOOP
UTL_FILE.PUT_LINE
(TO_CHAR (emprec.empno) || ',' ||
emprec.ename || ',' ||
...
TO_CHAR (emprec.deptno));
END LOOP;

UTL_FILE.FCLOSE (fileID);
END;
PUT_LINE相当于PUT后加上NEW_LINE;也相当于PUTF的格式串"%s\n"。

UTL_FILE.PUTF
以一个模版样式输出至多5个字符串,类似C中的printf

PROCEDURE UTL_FILE.PUTF
(file IN FILE_TYPE
,format IN VARCHAR2
,arg1 IN VARCHAR2 DEFAULT NULL
,arg2 IN VARCHAR2 DEFAULT NULL
,arg3 IN VARCHAR2 DEFAULT NULL
,arg4 IN VARCHAR2 DEFAULT NULL
,arg5 IN VARCHAR2 DEFAULT NULL);
file
由FOPEN返回的文件句柄
format
决定格式的格式串
argN
可选的5个参数,最多5个

格式串可使用以下样式
%s
在格式串中可以使用最多5个%s,与后面的5个参数一一对应
\n
换行符。在格式串中没有个数限制
%s会被后面的参数依次填充,如果没有足够的参数,%s会被忽视,不被写入文件

UTL_FILE.PUTF会产生以下异常
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR

UTL_FILE.FFLUSH
确保所有数据写入文件。
PROCEDURE UTL_FILE.FFLUSH (file IN UTL_FILE.FILE_TYPE);
file
由FOPEN返回的文件句柄

操作系统可能会缓存数据来提高性能。因此可能调用put后,打开文件却看不到写入的数据。在关闭文件前要读取数据的话可以使用UTL_FILE.FFLUSH。
典型的使用方法包括分析执行进度和调试纪录。
UTL_FILE.FFLUSH会产生以下异常
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR

UTL_FILE.FCLOSE
关闭文件
PROCEDURE UTL_FILE.FCLOSE (file IN OUT FILE_TYPE);
file
由FOPEN返回的文件句柄

注意file是一个IN OUT参数,因为在关闭文件后会设置为NULL
当试图关闭文件时有缓存数据未写入文件,会抛出WRITE_ERROR异常

UTL_FILE.FCLOSE会产生以下异常
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.WRITE_ERROR

UTL_FILE.FCLOSE_ALL
关闭所有已打开的文件
PROCEDURE UTL_FILE.FCLOSE_ALL;

在结束程序时要确保所有打开的文件已关闭,可使用FCLOSE_ALL
也可以在EXCEPTION使用,当异常退出时,文件也会被关闭。
EXCEPTION
WHEN OTHERS

THEN
UTL_FILE.FCLOSE_ALL;
... other clean up activities ...
END;

注意:当使用FCLOSE_ALL关闭所有文件时,文件句柄并不会标记为NULL,使用IS_OPEN会返回TRUE。但是,那些关闭的文件不能执行读写操作(除非你再次打开文件)。
UTL_FILE.FCLOSE_ALL会产生以下异常
UTL_FILE.WRITE_ERROR