DBMS_LOB
1.LOB背景
在现在的系统开发中,需要存储的已不仅仅是简单的文字信息,也包括一些图片、音像资料或者超长的文本,这要求后台数据库具有存储这些数据的能力,Oracle通过提供LOB对象实现了该功能。
2.LOB
在ORACLE数据库中,LOB大对象类型是用来存储大量的二进制和文本数据的一种数据类型(一个LOB字段可存储达4GB的数据)。目前LOB分为内部LOB和外部LOB。
2.1 内部LOB
内部LOB将数据以字节流的形式存储在数据库的内部,因而内部LOB的许多操作都可以参与事务,也可以像处理普通数据一样对其进行备份和恢复操作。
Oracle支持的三种内部LOB为:BLOB(二进制数据)、CLOB(单字节字符数据)、NCLOB(多字节国家字符数据)。其中CLOB和NCLOB类型适用于存储超长的文本数据,BLOB类型适用于存储大量的二 进制数据,如图像、视频等。
2.2 外部LOB
ORACLE仅支持一种外部LOB类型:BFILE类型。在数据库内,该类型仅存储数据在操作系统中的位置信息,而数据的实体 以外部文件的形式存在与操作系统的文件系统中。因而该类型所表示的数据时只读的,不参与事务。该类型可帮助用户管理大量的由外部程序访问的文件。
3.LOB的使用
ORACLE提供了多种使用和维护LOB的方式,如使用PL/SQL中的DBMS_LOB包,调用OCI(Oracle Call Interface)、使用Proc*C/C++、使用JDBC等。其中最方便有效的是使用PLSQL调用的DBMS_LOB包。
在ORACLE中,存储在LOB中的数据称为LOB的值,如使用SELECT对某一LOB字段进行选择查询,则返回的不是LOB的值,而是该LOB字段的定位器(相当于定向LOB值的指针),DBMS_LOB包中提供的所有函数和过程都以LOB定位器作为参数。
3.1 DBMS_LOB过程
DBMS_LOB包中主要提供以下几个过程供用户对内部LOB字段进行维护:
APPEND:将源LOB中的内容加到目的LOB中。
CLOSE:关闭已经打开的LOB。
CREATETEMPORARY:在用户的临时表空间中,建立临时LOB。
FILECLOSE:关闭打开的BFILE定位符所指向的OS文件。
FILECLOSEALL:关闭当前会话已经打开的所有BFILE文件。
FILEEXISTS:确定file_loc对应的OS文件是否存在,1:存在。0:不存在。
FILEGETNAME:获取BFILE定位符所对应的目录别名和文件名。
FILEISOPEN:确定BFILE对应的OS文件是否打开。
FREETEMPORARY:释放在默认临时表空间中的临时LOB。
FILEOPEN:打开文件。
GETCHUNKSIZE:当建立包含CLOB/BLOB列的表时,通过指定CHUNK参数可以指定操纵LOB需要分配的字节数(数据库尺寸的整数倍)默认为数据块的尺寸。
COPY:从源LOB中复制数据到目的LOB。
ERASE:删除LOB中全部或部分内容。
TRIM:将LOB值减少到指定的长度。
WRITE:向LOB中写入数据。
INSTR:返回特定样式数据从LOB某偏移位置开始出现N次的具体位置。
IDOPEN:确定LOB是否打开,打开:1,未打开:0。
ISTEMPORARY:确定定位符是否为临时LOB。
LOADFROMFILE:将BFILE的部分或全部内容复制到目标LOB变量。
LOADBLOBFROMFILE:将BFILE数据装载到BLOB中,并且在装载后取得最新的偏移位置。
OPEN:打开LOB,open_mode(只读:dbms_lob.lob_readonly,写:dbms_lob.lob_readwrite)。
COMPARE:比较两个同种数据类型的LOB的部分或全部值是否相同。
GETLENGTH:获取LOB的长度。
READ:从LOB中读出数据。
SUBSTR:与字符处理函数SUBSTR使用方法一样。
WRITEAPPEND:将缓冲区数据写到LOB尾部。
3.2 常用过程
3.2.1 写入对象
PROCEDURE WRITE(lob_loc IN OUT BLOB,
amount IN BINARY_INTEGER,
offset IN INTEGER,
buffer IN RAW);
PROCEDURE WRITE(lob_loc IN OUT CLOB CHARACTER SET any_cs,
amount IN BINARY_INTEGER,
offset IN INTEGER,
buffer IN VARCHAR2 CHARACTER SET lob_loc%charset);
各参数的含义为:
lob_loc:要写入的LOB定位器。
amount:写入LOB中的字节数。
offset:指定开始操作的偏移量。
buffer:指定写操作的缓冲区。
实例: DECLARE
obloc 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)缓冲区的最大容量为32767字节,因此在写入大量数据时需多次调用该过程。
3.2.2 读取对象
PROCEDURE WRITE(lob_loc IN OUT BLOB,
amount IN BINARY_INTEGER,
offset IN INTEGER,
buffer IN RAW);
PROCEDURE WRITE(lob_loc IN OUT CLOB CHARACTER SET any_cs,
amount IN BINARY_INTEGER,
offset IN INTEGER,
buffer IN VARCHAR2 CHARACTER SET lob_loc%charset);
参数的含义为:
lob_loc:要写入的LOB定位器。
amount:写入LOB中的字节数。
offset:指定开始操作的偏移量。
buffer:指定写操作的缓冲区。
实例: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;
3.2.3 复制对象
append存储过程用于将一个大对象添加到另一个大对象中,此时是将源大对象的内容全部添加过去
PROCEDURE append(dest_lob IN OUT NOCOPY BLOB,
src_lob IN BLOB);
PROCEDURE append(dest_lob IN OUT NOCOPY CLOB CHARACTER SET any_cs,
src_lob IN CLOB CHARACTER SET dest_lob%charset);
各个参数的含义如下:
dest_lob是被源lob添加到的目标lob的定位器。
src_lob是源lob的定位器。
any_cs用来指定字符集。
实例:VARCHAR类型的字符串最多只能存储32767个字符,超出这一长度后,将自动截取字符串到长度32767,导致部门输出内容丢失,甚至报错。
解决办法:可采用clob对象来保存
1.定义clob对象:l_table_rowspan_clob CLOB; --字符型的大对象
2.创建临时LOB: dbms_lob.createtemporary(l_table_rowspan_clob, TRUE);
3.将缓冲区数据写入到LOB中的特定位置:
l_table_line为报表输出字符串拼接对象,将l_table_line内容写入clob对象中
l_clob_lengnth := nvl(dbms_lob.getlength(l_table_rowspan_clob),0); --初始位置
dbms_lob.write(lob_loc => l_table_rowspan_clob, --是要操作的大型对象定位器
amount => length(l_table_line), --是要写到大型对象中去的字节数量
offset => l__clob_lengnth + 1, --是指定将数据写入到大型对象什么位置的偏移地址
buffer => l_table_line); --是写入到大型对象的数据缓冲区
l_clob_lengnth := nvl(dbms_lob.getlength(l_table_rowspan_clob),0); --最终位置
4.读取CLOD对象的内容
dbms_lob.read(lob_loc => l_table_rowspan_clob,
amount => l_r_amount,--要读取的字符数
offset => l_r_offset_start,--开始读取字符数的位置
buffer => l_r_buffer); --存储读取到数据的变量
l_r_amount := 16383;--定义每一次读取字符的数量 l_clob_index := 0; LOOP l_clob_index := l_clob_index + 1; EXIT WHEN l_r_clob_length <= 0; dbms_lob.read(lob_loc => l_table_rowspan_clob, amount => l_r_amount, offset => l_r_offset_start, buffer => l_r_buffer); l_r_clob_length := l_r_clob_length - l_r_amount; l_r_offset_start := l_r_offset_start + l_r_amount; IF l_r_clob_length <= 0 THEN --下一次循环结束 IF l_clob_index = 1 THEN --第一次循环 --写文本到一个文件,不附加任何新行字符 fnd_file.put(fnd_file.output, substr(l_r_buffer, 12, length(l_r_buffer) - 11)); --cux_conc_utl.out_msg(substr(l_r_buffer, 12, length(l_r_buffer)-11)); ELSE --写文本到一个文件,不附加任何新行字符 fnd_file.put(fnd_file.output, substr(l_r_buffer, 1, length(l_r_buffer) - 11)); --cux_conc_utl.out_msg(substr(l_r_buffer, 1, length(l_r_buffer)-11)); END IF; --IF l_clob_index = 1 THEN--第一次循环 ELSE IF l_clob_index = 1 THEN --第一次循环 --写文本到一个文件,不附加任何新行字符 fnd_file.put(fnd_file.output, substr(l_r_buffer, 12)); --cux_conc_utl.out_msg(substr(l_r_buffer, 12)); ELSE --写文本到一个文件,不附加任何新行字符 fnd_file.put(fnd_file.output, l_r_buffer); --cux_conc_utl.out_msg(l_r_buffer); END IF; --IF l_clob_index = 1 THEN --第一次循环 END IF; -- IF l_r_clob_length <= 0 THEN--下一次循环结束 END LOOP;
DBMS_LOB的更多相关文章
- DBMS_LOB包的使用
DBMS_LOB包的使用 1. dbms_lob.append( dest_lob IN OUT NOCOPY BLOB, src_lob IN BLOB) dbms_lob.appen ...
- dbms_lob使用之-基础
在Oracle中,存储在LOB中数据称为LOB的值,如使用Select 对某一LOB字段进行选择,则返回的不是LOB的值,而是该LOB字段的定位器(可以理解为指向LOB值的指针).如执行如下 ...
- [转载]DBMS_LOB
1.LOB背景 在现在的系统开发中,需要存储的已不仅仅是简单的文字信息,也包括一些图片.音像资料或者超长的文本,这要求后台数据库具有存储这些数据的能力,Oracle通过提供LOB对象实现了该功能. 2 ...
- [转载]dbms_lob用法小结
http://blog.sina.com.cn/s/blog_713978a50100prkt.html CLOB里存的是2进制 判定长度 DBMS_LOB.GETLENGTH(col1)获取文本 ...
- 在使用DBMS_LOB.WRITEAPPEND()追加Clob内容的时候,报数字或值异常
在实际的使用中有可能会使用DBMS_LOB.WRITEAPPEND()去将Clob内容作为buffer增加到我们需要的对象中,但是在实际的使用中Clob大小往往是超过32767长度的,然而DBMS_L ...
- DBMS_LOB的简单用法以及释放DBMS_LOB生成的临时CLOB内存
dbms_lob包(一) dbms_lob包(二) 如何释放DBMS_LOB.CREATETEMPORARY的空间 Temporary LOB导致临时表空间暴满. oracle数据库中的大对象1——永 ...
- Oracle中DBMS_LOB包使用小结
本文主要介绍oracle数据库中dbms_lob包的使用以及使用dbms_lob包来维护lob数据库类型的基本方法.随着社会的发展,在现代信息系统的开发中,需要存储的已不仅仅是简单的文字信息,同时还包 ...
- 2个sql 函数dbms_lob.substr 和 wm_concat
转自: http://blog.csdn.net/wenzhongyan/article/details/50315473 http://blog.csdn.net/ojerryzuo/article ...
- dbms_lob包学习笔记之三:instr和substr存储过程
instr和substr存储过程,分析内部大对象的内容 instr函数与substr函数 instr函数用于从指定的位置开始,从大型对象中查找第N个与模式匹配的字符串. 用于查找内部大对象中的字符串的 ...
随机推荐
- js判断浏览器类型和内核
function judge() { var sUserAgent = navigator.userAgent.toLocaleLowerCase(); var isLinux = (String(n ...
- 为PHP增加PDO-Mysql驱动
一.问题 公司有一台老的Linux服务器,Apache+MySQL+Php结构的, 要把最近做的一个PHP项目部署到上面,做为测试环境, 由于新项目是用PHP的YII框架开发的,而YII框架的数据访问 ...
- LT1619EMS8 锂电池 升压电路分析
LT1619EMS8 锂电池 升压电路分析 本文主要是分析LT1619EMSB锂电池升压芯片电路,知道其大致是怎么工作的,其中的一些电阻该如何配置. 2016-1-23 深圳 南山平山村 曾剑锋 一. ...
- 数学语言和程序语言的对比:面向过程与面向集合&命题
共同之处:都使用字符串或数值来引用一个客观实体.当然数字和字符串也可以作为实体对象,这取决于人的解释. 不同之处:数学语句每一行都给出了一个结论, 程序语句的每一行都定义了一个过程.注意这里所指的程序 ...
- 【转】linux : waitpid函数
原文网址:http://blog.csdn.net/jifengszf/article/details/3067841 [waitpid系统调用] 功能描述: 等待进程改变其状态.所有下面 ...
- Solr DIH以Mysql为数据源批量创建索引
演示使用solr管理后台,以mysql为数据源,批量建索引的方法 测试于:Solr 4.5.1, mmseg4j 1.9.1, Jdk 1.6.0_45, Tomcat 6.0.37 | CentOS ...
- ios 照片编辑的view封装
转:http://www.cnblogs.com/xiaobaizhu/archive/2013/07/03/3170101.html 该控件有旋转,缩放,拖动,剪裁的功能,封装成了一个ImageCr ...
- GitHub上README.md教程
最近对它的README.md文件颇为感兴趣.便写下这贴,帮助更多的还不会编写README文件的同学们. README文件后缀名为md.md是markdown的缩写,markdown是一种编辑博客的语言 ...
- Ubuntu 出现 apt-get问题的解决方法
ubuntu 10.10 sudo apt-get update 404 Not Found or W: Failed to fetch http://cn.old-releases.ubuntu. ...
- UI篇--Android中3种方法实现back键动作
方法一:重写onBackPressed方法 @Override public void onBackPressed() { // do something what you want super.on ...