PL/SQL块定义部分之四LOB类型
来源:互联网 发布:淘宝有版权被投诉 编辑:程序博客网 时间:2024/05/29 03:50
在Oracle的早期版本中,使用LONG和LONG RAW类型存放大数据。从8i版本开始,Oracle引入了LOB数据类型,并且Oracle建议开发人员尽量去使用LOB类型而不去使用LONG和LONGRAW。LOB类型和LONG、LONGRAW类型相比有几个不同的地方。如:
1、LOB(除了NCOLB)可以作为对象类型的一个属性,但LONG类型不可以。
2、LOB的最大值是4G,而LONG只有2G。
3、LOB支持随机访问数据,但LONG只支持顺序访问。
LOB包括内部LOB和外部LOB,其中内部LOB(BLOB CLOBNLOB)的数据存放到数据库中,而外部LOB(BFILE)的数据存放在操作系统的文件中。具体说明如下:
BLOB:存放二进制格式的数据,如:图像、音频、视频等。
CLOB:存放数据库字符集格式的字符数据,如:大的文本数据。
NCLOB:存放Unicode字符集的字符数据。
BFILE:存放指向操作系统文件的指针,并且该文件即可以是文本文件,也可以是二进制文件。当我们访问该类型所表示的列时,只能读取数据,不能修改。
一、理解什么是LOB定位器和LOB数据
LOB数据是我们存入到数据库中的值,而LOB定位器是操作这些值的指针。当我们想读取或者修改LOB数据时,我们必须先要获取LOB定位器,然后通过LOB定位器才能读取或者修改LOB数据,下面的示例能够帮助我们更好的理解LOB数据和LOB定位器:
DECLARE
picLOB BLOB;
BEGIN
--假定picColumn列是BLOB类型
SELECT picColumn INTO picLOB FROM myTable WHERE ID=10;
END;
当SELECTINTO语句执行完之后,picLOB变量将被赋值,但是picLOB变量的值不是LOB数据,而是LOB数据的定位器。要想获取LOB数据,我们必须对定位器进行操作,Oracle中DBMS_LOB包里的很多函数和过程都可以对定位器进行操作,如下:
APPEND(): 将源LOB中的内容加到目的LOB中
COPY() :从源LOB中复制数据到目的LOB
ERASE(): 删除LOB中全部或部分内容
TRIM(): 将LOB值减少到指定的长度
WRITE(): 向LOB 中写入数据
COMPARE(): 比较两个同种数据类型的LOB的部分或全部值是否相同
GETLENGTH(): 获取LOB的长度
READ(): 从LOB中读出数据
二、使用CLOB数据类型
示例1:创建带有CLOB数据类型的表,并插入数据
CREATE TABLE CLOB_TABLE
(
id NUMBER(3) PRIMARY KEY,
remarkCLOB --remark:备注
);
INSERT INTO CLOB_TABLE(id) VALUES(1); --remark列没有定位器,并且没有数据
INSERT INTO CLOB_TABLEVALUES(2,'ID为2的备注信息'); --remark列有定位器,并且有数据
INSERT INTO CLOB_TABLEVALUES(3,empty_clob());--remark含有定位器,但是没有数据
检索定位器的值:
DECLARE
myLob CLOB;
BEGIN
SELECT remark INTO myLob FROM CLOB_TABLE WHEREid=___;
IF myLob ISNULL THEN
DBMS_OUTPUT.PUT_LINE('myLob ISNULL');
ELSE
DBMS_OUTPUT.PUT_LINE(myLob);
END IF;
END;
当下划线填入1时,结果如下:
myLob IS NULL
当下划线填入2时,结果如下:--打印出定位器所指向的数据
ID为2的备注信息
当下划线填入3时,没有打印出信息。
修改id为1的remark列,使其具有定位器:
UPDATE CLOB_TABLE SETremark=empty_clob() WHERE id=1;
这时再调用以上的代码块,这次没有打印出信息。
示例2:向CLOB列追加数据
DECLARE
myLob CLOB;
buffer VARCHAR2(20) := '这是第一次追加的内容';
amount INT;
offset INT;
BEGIN
--要想能够修改LOB数据,必须指定FOR UPDATE子句
SELECT remark INTO myLob FROM CLOB_TABLE WHEREid=2 FOR UPDATE;
amount:=LENGTH(buffer); --获取追加文本的长度
offset:=DBMS_LOB.GETLENGTH(myLob)+1; --获取定位器引用的LOB数据的长度
DBMS_LOB.WRITE(myLob,amount,offset,buffer);--向CLOB列追加数据,每次最大追加32767字节。要注意必须先存在定位器才能追加数据,否则会出现invalidLOB locator specified:ORA-22275错误。
--DBMS_LOB.WRITEAPPEND(myLob,amount,buffer);--使用这个函数不用考虑offset参数
END;
示例3:读取CLOB数据
DECLARE
myLob CLOB;
text VARCHAR2(40) := '这是第三次追加的内容';
amount INT;
offset INT;
BEGIN
SELECT remark INTO myLob FROM CLOB_TABLE WHEREid=2;
amount:=15;
offset:=3;
--从LOB数据中的第三个字符开始读取共读取15个字符放入到text变量
DBMS_LOB.READ(myLob,amount,offset,text);
DBMS_OUTPUT.PUT_LINE(text);
END;
三、使用BFile数据类型
BFile类型不存放文件实际数据,而是存放文件的指针,文件的数据存储在操作系统的文件系统上,并且我们只能通过BFile类型读取文件的数据,不能修改。
示例1:创建ScottDir目录,并授予scott用户读权限
CREATE DIRECTORY ScottDir AS'E:/ScottDir';--注意此语句并不会在操作系统上创建文件夹
GRANT READ ON DIRECTORY ScottDirTO scott;
示例2:创建含有BFile数据类型的列,并插入数据
CREATE TABLE BFILE_TABLE
(
id NUMBER PRIMARY KEY,
remark BFILE
);
插入数据:
INSERT INTO BFILE_TABLE(id) VALUES(1);
UPDATE BFILE_TABLE SET remark=BFILENAME('SCOTTDIR','1.txt');
INSERT INTO BFILE_TABLE(id,remark) VALUES(2,BFILENAME('SCOTTDIR','2.doc'));
注意:BFILE数据类型指向的文件,即可以是文本文件也可以是二进制文件。而且BFILE数据类型不能通过SELECT语句直接查看其内容。
示例3:将BFile文件的内容读取到CLOB列(前提是BFile文件是文本文件)
DECLARE
src BFILE;
des CLOB;
amount INT;
src_offset INT :=1;
des_offset INT :=1;
csid INT :=850;
lc INT :=0;
warning INT;
BEGIN
SELECT remark INTO src FROM BFile_TABLE WHEREid=1;
SELECT remark INTO des FROM CLOB_TABLE WHEREid=1 FOR UPDATE;
DBMS_LOB.FILEOPEN(src,DBMS_LOB.FILE_READONLY);
amount:=DBMS_LOB.GETLENGTH(src);
DBMS_OUTPUT.PUT_LINE(amount);
DBMS_LOB.LOADCLOBFROMFILE(des,src,amount,des_offset,src_offset,csid,lc,warning);
DBMS_LOB.CLOSE(src);
END;
四、使用BLOB数据类型
示例1:创建带有BLOB列的表并插入数据
CREATE TABLE BLOB_TABLE
(
id NUMBER(3),
remark BLOB
);
INSERT INTO BLOB_TABLE VALUES(1,EMPTY_BLOB());
将文件内容插入到BLOB列:
DECLARE
src BFILE;
des BLOB;
amount INT;
src_offset INT :=1;
des_offset INT :=1;
csid INT :=0;
lc INT :=0;
warning INT;
BEGIN
src:=BFILENAME('SCOTTDIR','2.doc');
SELECT remark INTO des FROM BLOB_TABLE WHEREid=1 FOR UPDATE;
DBMS_LOB.FILEOPEN(src,DBMS_LOB.FILE_READONLY);
amount:=DBMS_LOB.GETLENGTH(src);
DBMS_OUTPUT.PUT_LINE(amount);
--DBMS_LOB.LOADBLOBFROMFILE(des,src,amount,des_offset,src_offset);
DBMS_LOB.CLOSE(src);
END;
1、LOB(除了NCOLB)可以作为对象类型的一个属性,但LONG类型不可以。
2、LOB的最大值是4G,而LONG只有2G。
3、LOB支持随机访问数据,但LONG只支持顺序访问。
LOB包括内部LOB和外部LOB,其中内部LOB(BLOB CLOBNLOB)的数据存放到数据库中,而外部LOB(BFILE)的数据存放在操作系统的文件中。具体说明如下:
BLOB:存放二进制格式的数据,如:图像、音频、视频等。
CLOB:存放数据库字符集格式的字符数据,如:大的文本数据。
NCLOB:存放Unicode字符集的字符数据。
BFILE:存放指向操作系统文件的指针,并且该文件即可以是文本文件,也可以是二进制文件。当我们访问该类型所表示的列时,只能读取数据,不能修改。
一、理解什么是LOB定位器和LOB数据
LOB数据是我们存入到数据库中的值,而LOB定位器是操作这些值的指针。当我们想读取或者修改LOB数据时,我们必须先要获取LOB定位器,然后通过LOB定位器才能读取或者修改LOB数据,下面的示例能够帮助我们更好的理解LOB数据和LOB定位器:
DECLARE
picLOB BLOB;
BEGIN
--假定picColumn列是BLOB类型
SELECT picColumn INTO picLOB FROM myTable WHERE ID=10;
END;
当SELECTINTO语句执行完之后,picLOB变量将被赋值,但是picLOB变量的值不是LOB数据,而是LOB数据的定位器。要想获取LOB数据,我们必须对定位器进行操作,Oracle中DBMS_LOB包里的很多函数和过程都可以对定位器进行操作,如下:
APPEND(): 将源LOB中的内容加到目的LOB中
COPY() :从源LOB中复制数据到目的LOB
ERASE(): 删除LOB中全部或部分内容
TRIM(): 将LOB值减少到指定的长度
WRITE(): 向LOB 中写入数据
COMPARE(): 比较两个同种数据类型的LOB的部分或全部值是否相同
GETLENGTH(): 获取LOB的长度
READ(): 从LOB中读出数据
二、使用CLOB数据类型
示例1:创建带有CLOB数据类型的表,并插入数据
CREATE TABLE CLOB_TABLE
(
id NUMBER(3) PRIMARY KEY,
remarkCLOB --remark:备注
);
INSERT INTO CLOB_TABLE(id) VALUES(1); --remark列没有定位器,并且没有数据
INSERT INTO CLOB_TABLEVALUES(2,'ID为2的备注信息'); --remark列有定位器,并且有数据
INSERT INTO CLOB_TABLEVALUES(3,empty_clob());--remark含有定位器,但是没有数据
检索定位器的值:
DECLARE
myLob CLOB;
BEGIN
SELECT remark INTO myLob FROM CLOB_TABLE WHEREid=___;
IF myLob ISNULL THEN
DBMS_OUTPUT.PUT_LINE('myLob ISNULL');
ELSE
DBMS_OUTPUT.PUT_LINE(myLob);
END IF;
END;
当下划线填入1时,结果如下:
myLob IS NULL
当下划线填入2时,结果如下:--打印出定位器所指向的数据
ID为2的备注信息
当下划线填入3时,没有打印出信息。
修改id为1的remark列,使其具有定位器:
UPDATE CLOB_TABLE SETremark=empty_clob() WHERE id=1;
这时再调用以上的代码块,这次没有打印出信息。
示例2:向CLOB列追加数据
DECLARE
myLob CLOB;
buffer VARCHAR2(20) := '这是第一次追加的内容';
amount INT;
offset INT;
BEGIN
--要想能够修改LOB数据,必须指定FOR UPDATE子句
SELECT remark INTO myLob FROM CLOB_TABLE WHEREid=2 FOR UPDATE;
amount:=LENGTH(buffer); --获取追加文本的长度
offset:=DBMS_LOB.GETLENGTH(myLob)+1; --获取定位器引用的LOB数据的长度
DBMS_LOB.WRITE(myLob,amount,offset,buffer);--向CLOB列追加数据,每次最大追加32767字节。要注意必须先存在定位器才能追加数据,否则会出现invalidLOB locator specified:ORA-22275错误。
--DBMS_LOB.WRITEAPPEND(myLob,amount,buffer);--使用这个函数不用考虑offset参数
END;
示例3:读取CLOB数据
DECLARE
myLob CLOB;
text VARCHAR2(40) := '这是第三次追加的内容';
amount INT;
offset INT;
BEGIN
SELECT remark INTO myLob FROM CLOB_TABLE WHEREid=2;
amount:=15;
offset:=3;
--从LOB数据中的第三个字符开始读取共读取15个字符放入到text变量
DBMS_LOB.READ(myLob,amount,offset,text);
DBMS_OUTPUT.PUT_LINE(text);
END;
三、使用BFile数据类型
BFile类型不存放文件实际数据,而是存放文件的指针,文件的数据存储在操作系统的文件系统上,并且我们只能通过BFile类型读取文件的数据,不能修改。
示例1:创建ScottDir目录,并授予scott用户读权限
CREATE DIRECTORY ScottDir AS'E:/ScottDir';--注意此语句并不会在操作系统上创建文件夹
GRANT READ ON DIRECTORY ScottDirTO scott;
示例2:创建含有BFile数据类型的列,并插入数据
CREATE TABLE BFILE_TABLE
(
id NUMBER PRIMARY KEY,
remark BFILE
);
插入数据:
INSERT INTO BFILE_TABLE(id) VALUES(1);
UPDATE BFILE_TABLE SET remark=BFILENAME('SCOTTDIR','1.txt');
INSERT INTO BFILE_TABLE(id,remark) VALUES(2,BFILENAME('SCOTTDIR','2.doc'));
注意:BFILE数据类型指向的文件,即可以是文本文件也可以是二进制文件。而且BFILE数据类型不能通过SELECT语句直接查看其内容。
示例3:将BFile文件的内容读取到CLOB列(前提是BFile文件是文本文件)
DECLARE
src BFILE;
des CLOB;
amount INT;
src_offset INT :=1;
des_offset INT :=1;
csid INT :=850;
lc INT :=0;
warning INT;
BEGIN
SELECT remark INTO src FROM BFile_TABLE WHEREid=1;
SELECT remark INTO des FROM CLOB_TABLE WHEREid=1 FOR UPDATE;
DBMS_LOB.FILEOPEN(src,DBMS_LOB.FILE_READONLY);
amount:=DBMS_LOB.GETLENGTH(src);
DBMS_OUTPUT.PUT_LINE(amount);
DBMS_LOB.LOADCLOBFROMFILE(des,src,amount,des_offset,src_offset,csid,lc,warning);
DBMS_LOB.CLOSE(src);
END;
四、使用BLOB数据类型
示例1:创建带有BLOB列的表并插入数据
CREATE TABLE BLOB_TABLE
(
id NUMBER(3),
remark BLOB
);
INSERT INTO BLOB_TABLE VALUES(1,EMPTY_BLOB());
将文件内容插入到BLOB列:
DECLARE
src BFILE;
des BLOB;
amount INT;
src_offset INT :=1;
des_offset INT :=1;
csid INT :=0;
lc INT :=0;
warning INT;
BEGIN
src:=BFILENAME('SCOTTDIR','2.doc');
SELECT remark INTO des FROM BLOB_TABLE WHEREid=1 FOR UPDATE;
DBMS_LOB.FILEOPEN(src,DBMS_LOB.FILE_READONLY);
amount:=DBMS_LOB.GETLENGTH(src);
DBMS_OUTPUT.PUT_LINE(amount);
--DBMS_LOB.LOADBLOBFROMFILE(des,src,amount,des_offset,src_offset);
DBMS_LOB.CLOSE(src);
END;
- PL/SQL块定义部分之四LOB类型
- pl/sql LOB类型
- PL/SQL之LOB类型和BIND变量
- PL/SQL变量中的LOB类型
- PL/SQL之块、标识符、基本变量类型实战
- PL/SQL定义部分之二复合数据类型
- pl/sql之定义并使用变量,复合类型
- pl/sql之定义并使用变量,复合类型
- PL/SQL简单语句块,变量定义
- oracle的PL/SQL定义类型
- PL/SQL之四 触发器
- PL/SQL之触发器类型
- PL/SQL语句块的定义、声明、赋值
- Oracle笔记 六、PL/SQL简单语句块、变量定义
- Oracle笔记 六、PL/SQL简单语句块、变量定义
- Oracle笔记 六、PL/SQL简单语句块、变量定义
- Oracle笔记 六、PL/SQL简单语句块、变量定义
- Oracle笔记 六、PL/SQL简单语句块、变量定义
- C#多线程学习(三) 生产者和消费者
- hdu acm 1913 Computers
- 字符串处理函数
- treeview节点查找
- C#线程系列讲座(1):BeginInvoke和EndInvoke方法
- PL/SQL块定义部分之四LOB类型
- C#线程系列讲座(2):Thread类的应用
- 混合环境下WMI 远程连接常见问题解决方法(Remote access)
- 日志模块(一头文件就实现了日志记录)
- 趣味面试题集锦
- 数据库隔离级别 (转自http://blog.csdn.net/enlicliu/archive/2009/02/23/3930499.aspx)
- java调用c++写的dll 出现由于应该程序配置不正确,应用程序未能启动
- 不舍红尘,只因恋上你
- 论文的阅读