/* *使用LOB对象 */ --LOB(Large Object)是专门用于处理大对象的一种数据类型,其所存放的数据长度可以达到4G字节 --CLOB/NCLOB用于存储大批量字符数据,BLOB用于存储大批量二进制数据,而BFILE则存储着指向OS文件的指针 /* *综合实例 */ --建立表空间 --#指定区尺寸为128k,如不指定,区尺寸默认为64k CREATE TABLESPACE EAS_D_HAIYA_STANDARD DATAFILE '/oracleDB/oradata/db/EAS_D_HAIYA_STANDARD.ORA' SIZE 500M;-- UNIFORM SIZE 128k; DROP TABLESPACE EAS_D_HAIYA_STANDARD INCLUDING CONTENTS AND DATAFILES; --建立临时表空间 CREATE TEMPORARY TABLESPACE EAS_T_HAIYA_STANDARD TEMPFILE '/oracleDB/oradata/db/EAS_T_HAIYA_STANDARD.ORA' SIZE 50M; DROP TABLESPACE EAS_T_HAIYA_STANDARD INCLUDING CONTENTS AND DATAFILES; --创建用户并指定表空间 create user haiya identified by kingdee default tablespace EAS_D_HAIYA_STANDARD temporary tablespace EAS_T_HAIYA_STANDARD; drop user haiya cascade; --建立表空间(这样建立表空间才能不报错) Create tablespace EAS_D_HAIYA_STANDARD Datafile '/oracleDB/oradata/db/EAS_D_HAIYA_STANDARD.ORA' size 10000M reuse autoextend on next 2M maxsize unlimited; Create temporary tablespace EAS_T_HAIYA_STANDARD TEMPFILE '/oracleDB/oradata/db/EAS_T_HAIYA_STANDARD.ORA' size 500M reuse autoextend on next 1M maxsize unlimited; create user haiya Identified by kingdee Default tablespace EAS_D_HAIYA_STANDARD temporary tablespace EAS_T_HAIYA_STANDARD Quota unlimited on EAS_D_HAIYA_STANDARD; --给用户赋DBA权限 grant dba to haiya; revoke dba from haiya; Grant create session,create table,create procedure,create sequence,create trigger,create view,SELECT ANY DICTIONARY to haiya; --之后操作以haiya用户登录 --一.查询ORACLE SERVER端的字符集 select userenv('language') from dual; select * from nls_database_parameters;--来源于props$,表示数据库的字符集 --查询客户端字符集环境 select * from nls_instance_parameters;--来源于v$parameter,表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表 --查询oracle client端的字符集 --在windows平台下,就是注册表里面相应OracleHome的NLS_LANG。还可以在dos窗口里面自己设置, --比如: set nls_lang=AMERICAN_AMERICA.ZHS16GBK --这样就只影响这个窗口里面的环境变量。 --在unix平台下,就是环境变量NLS_LANG.$echo $NLS_LANGAMERICAN_AMERICA.ZHS16GBK --如果检查的结果发现server端与client端字符集不一致,请统一修改为同server端相同的字符集。 --二.修改server端字符集(不建议使用) --1.关闭数据库 --SQL>SHUTDOWN IMMEDIATE --2.启动到Mount --SQL>STARTUP MOUNT; --SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION; --SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; --SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0; --SQL>ALTER DATABASE OPEN; --SQL>ALTER DATABASE CHARACTER SET ZHS16GBK; --SQL>ALTER DATABASE national CHARACTER SET ZHS16GBK; --SQL>SHUTDOWN IMMEDIATE; --SQL>STARTUP --注意:如果没有大对象,在使用过程中进行语言转换没有什么影响,(切记设定的字符集必须是ORACLE支持,不然不能start) 按上面的做法就可以。 --若出现‘ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when NCLOB data exists’ 这样的提示信息, --要解决这个问题有两种方法 --1. 利用INTERNAL_USE 关键字修改区域设置, --2. 利用re-create,但是re-create有点复杂,所以请用internal_use --SQL>SHUTDOWN IMMEDIATE; --SQL>STARTUP MOUNT EXCLUSIVE; --SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION; --SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; --SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0; --SQL>ALTER DATABASE OPEN; --SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8; --SQL>SHUTDOWN immediate; --SQL>startup; --如果按上面的做法做,National charset的区域设置就没有问题 --1.使用CLOB数据类型 --创建CLOB_TABLE表如出现超出表空间的空间限量的错误,应重新创建表空间并如上用户 --以haiya用户登录 CREATE TABLE CLOB_TABLE ( id NUMBER(3) PRIMARY KEY, remark CLOB --remark:备注 ); INSERT INTO CLOB_TABLE(id) VALUES(1); --remark列没有定位器,并且没有数据 INSERT INTO CLOB_TABLE VALUES(2,'ID2'); --remark列有定位器,并且有数据 INSERT INTO CLOB_TABLE VALUES(3,empty_clob());--remark含有定位器,但是没有数据 select * from clob_table for update; --检索定位器的值: DECLARE myLob CLOB; BEGIN SELECT remark INTO myLob FROM CLOB_TABLE WHERE id=1; --1,2或者3 IF myLob IS NULL THEN DBMS_OUTPUT.PUT_LINE('myLob IS NULL'); ELSE DBMS_OUTPUT.PUT_LINE(myLob ); END IF; END; --修改id为1的remark列,使其具有定位器: UPDATE CLOB_TABLE SET remark=empty_clob() WHERE id=1; --向CLOB列追加数据 DECLARE myLob CLOB; buffer VARCHAR2(20) := '这是第一次追加的内容'; amount INT; offset INT; BEGIN --要想能够修改LOB数据,必须指定FOR UPDATE子句 SELECT remark INTO myLob FROM CLOB_TABLE WHERE id=2 FOR UPDATE ; amount:=LENGTH( buffer ); --获取追加文本的长度 offset:=DBMS_LOB.GETLENGTH (myLob)+1; --获取定位器引用的LOB数据的 长度 DBMS_LOB.WRITE(myLob,amount,offset, buffer );-- 向CLOB列追加数据,每次最大追加32767字节。要注意必须先存在定位器才能追加数据,否则会出现invalid LOB locator specified: ORA-22275错误。 --DBMS_LOB.WRITEAPPEND(myLob,amount, buffer );--使用这个函数不用考虑offset参数 END; --读取CLOB数据 DECLARE myLob CLOB; text VARCHAR2(40); amount INT; offset INT; BEGIN SELECT remark INTO myLob FROM CLOB_TABLE WHERE id=2; amount:=15; offset:=3; --从LOB数据中的第三个字符开始读取共读取15个字符放入到text变量 DBMS_LOB.READ(myLob,amount,offset,text); DBMS_OUTPUT.PUT_LINE(text); END; --2.使用BFILE数据类型 CREATE DIRECTORY TestDir as 'D:\TestDir'; --注意此语句不会在操作系统上创建文件夹 --创建含有BFile数据类型的列,并插入数据 CREATE TABLE BFILE_TABLE(ID NUMBER PRIMARY KEY,remark BFILE); --插入数据 insert into bfile_table(id) values(1); update bfile_table set remark=BFILENAME('TESTDIR','1.txt'); insert into bfile_table(id,remark) values(2,bfilename('TESTDIR','2.doc')); --注意:BFILE数据类型指向的文件,即可以是文本文件,也可以是二进制文件。 --而且BFILE数据类型不能通过SELECT语句直接查看其内容 --将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 WHERE id=1; SELECT remark INTO des FROM CLOB_TABLE WHERE id=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; --3.使用BLOB数据类型 --创建带有BLOB列的表并插入数据 CREATE TABLE BLOB_TABLE ( id NUMBER(3), remark BLOB ); INSERT INTO BLOB_TABLE VALUES(1,EMPTY_BLOB()); select * from blob_table; --将文件内容插入到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('TESTDIR','1.txt'); SELECT remark INTO des FROM BLOB_TABLE WHERE id=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; --DBMS_LOB包 --过程APPEND DECLARE dest_lob CLOB; src_lob CLOB; BEGIN src_lob:='中国'; dest_lob:='你好,'; dbms_lob.append(dest_lob,src_lob); dbms_output.put_line(dest_lob); END; --过程CLOSE:关闭已经打开的LOB,它不仅适用于CLOB/NCLOB和BLOB类型,也适用于BFILE类型 --语法如下:DBMS_LOB.CLOSE(lob_loc IN OUT NOCOPY BLOB/CLOB/BFILE); --函数COMPARE --注意,该函数只能用于比较同类型的LOB变量 --语法如下: --DBMS_LOB.COMPARE(lob_1 in BLOB/CLOB/BFILE,lob_2 in BLOB/CLOB/BFILE,amount in integer:=4294967295,offset_1 in integer:=1,offset_2 in integer:=1) return integer; --lob_1用于指定第一个LOB变量,lob_2用于指定第二个LOB变量,amount用于指定字符个数(CLOB)或字节个数(BLOB),offset_1用于指定第一个LOB的起始比较位置,offset_2用于指定第二个LOB的起始比较位置。 --如果比较结果相同,则返回0,如果比较结果不同,则返回一个非0的整数。 DECLARE dest_lob CLOB; src_lob CLOB; BEGIN src_lob:='中国'; dest_lob:='&content'; if dbms_lob.compare(src_lob,dest_lob)=0 then dbms_output.put_line('内容相同'); else dbms_output.put_line('内容不同'); end if; END; --过程COPY --该过程用于将源LOB变量的部分或全部内容复制到目标LOB变量中,它只适用于内部LOB类型(CLOB/NCLOB/BLOB),而不适用于BFILE类型 --语法如下: --DBMS_LOB.COPY(dest_lob in out NOCOPY BLOB/CLOB/NCLOB,src_lob in BLOB/CLOB/NCLOB,amount in integer,dest_offset in integer:=1,src_offset in integer:=1,src_offset in integer:=1); --dest_offset用于指定要复制到目标LOB变量的起始位置,src_offset用于指定源LOB变量中开始复制的起始位置。 DECLARE dest_lob clob; src_lob clob; amount int; BEGIN src_lob:='中国'; dest_lob:='你好,'; amount:=dbms_lob.getlength(src_lob); dbms_lob.copy(dest_lob,src_lob,amount,3); dbms_output.put_line(dest_lob); END; --过程CREATETEMPORARY --建立临时LOB,只适用于内部LOB类型(BLOB/CLOB/NCLOB),但不适用于BFILE类型。 --当执行该过程建立临时LOB时,ORACLE会将该临时LOB建立在用户的临时表空间中 --语法如下 --DBMS_LOB.CREATETEMPORARY(lob_loc in out NOCOPY BLOB/CLOB/NCLOB,cache in boolean,dur in pls_integer:=10); --lob_loc用于指定LOB定位符,cache用于指定是否要将LOB读取到缓冲区,dur用于指定何时清除临时LOB(10:会话结束清除临时LOB,12:调用结束清除临时LOB) DECLARE src_lob CLOB; begin dbms_lob.createtemporary(src_lob,true); end; --过程ERASE --用于删除LOB变量的全部内容或部分内容,只适用于内部LOB类型(BLOB/CLOB/NCLOB),而不适用于BFILE类型 DECLARE src_lob clob; offset int; amount int; begin src_lob:='欢迎使用PL/SQL编程指南'; amount:=10; offset:=5; dbms_lob.erase(src_lob,amount,offset); dbms_output.put_line(src_lob); end; --过程FILECLOSE --用于关闭已经打开的BFILE定位符所指向的OS文件 DBMS_LOB.fileclose(file_loc in out NOCOPY bfile); --过程FILECLOSEALL --用于关闭当前会话已经打开的所有BFILE文件 DBMS_LOB.filecloseall; --函数FILEEXISTS --用于确定BFILE定位符所指向的OS文件是否存在 DBMS_LOB.fileexists(file_loc in bfile) return integer; --如果文件存在,则返回1,如果文件不存在,则返回0 --以system用户登录,给当前用户赋创建directory的权限 grant create any directory to haiya; grant drop any directory to haiya;--(删除权限) --以haiya用户登录,创建一个目录 create or replace directory bfile_data as 'D:\'; DECLARE file1 BFILE; begin --创建bfile locator,使用bfilename函数,directory是大小写敏感的,一定要大写 file1:=bfilename('BFILE_DATA','README.DOC'); if dbms_lob.fileexists(file1) = 0 then dbms_output.put_line('文件不存在'); else dbms_output.put_line('文件存在'); end if; end; --过程FILEGETNAME --用于取得BFILE定位符所对应的目录别名和文件名 DECLARE dir_alias varchar2(20); filename varchar2(50); file_loc bfile; begin select remark into file_loc from BFILE_TABLE where id = &id; dbms_lob.filegetname(file_loc,dir_alias,filename); dbms_output.put_line('目录别名:'||dir_alias); dbms_output.put_line('文件名:'||filename); end; --函数FILEISOPEN --用于确定BFILE所对应的OS文件是否已经打开 --如果文件已经被打开,则返回1,如果文件没有被打开,则返回0 DECLARE file1 BFILE; BEGIN file1:=bfilename('TESTDIR','2.doc'); if dbms_lob.fileisopen(file1)=0 then dbms_output.put_line('文件未打开'); else dbms_output.put_line('文件已经打开'); end if; END; --过程FILEOPEN --用于打开BFILE所对应的OS文件 --注意,OS文件只能以只读方式打开 DECLARE file1 BFILE; BEGIN file1:=bfilename('TESTDIR','2.doc'); if dbms_lob.fileexists(file1) = 1 then dbms_lob.fileopen(file1); dbms_output.put_line('文件已经被打开'); end if; dbms_lob.fileclose(file1); END; --过程FREETEMPORARY --用于释放在默认临时表空间中的临时LOB DECLARE src_lob clob; begin dbms_lob.createtemporary(src_lob,true); src_lob:='中华人民共和国'; dbms_lob.freetemporary(src_lob); end; --函数GETCHUNKSIZE --当建立包含CLOB列或BLOB列的表时,通过指定CHUNK参数可以指定操纵LOB需要分配的字节数(该值是数据块尺寸的整数倍),如果不指定该参数,其 --默认值为数据块的尺寸。通过使用函数GETCHUNKSIZE,可以取得CHUNK参数对应的值 DECLARE src_lob clob; chunksize int; begin src_lob:='中华人民共和国'; chunksize:=dbms_lob.getchunksize(src_lob); dbms_output.put_line('CHUNK尺寸:'||chunksize); end; --函数GETLENGTH --用于取得LOB数据的实际长度,不仅适用于CLOB和BLOB类型,也适用于BFILE类型 DECLARE file1 bfile; length int; begin file1:=bfilename('TESTDIR','2.doc'); length:=dbms_lob.getlength(file1); dbms_output.put_line('文件长度:'||length); end; --函数INSTR --用于返回特定样式数所据在LOB中从某偏移位置开始第n次出现时的具体位置,它不仅适用于BLOB和CLOB类型,也适用于BFILE类型 DECLARE src_lob clob; location int; offset int; occurence int; begin src_lob:='中国,中国,伟大的中国'; offset:=2; occurence:=2; location:=dbms_lob.instr(src_lob,'中国',offset,occurence); dbms_output.put_line('从第'||offset||'字符开始,中国第'||occurence||'次出现的具体位置:'||location); end; --函数ISOPEN --用于确定LOB是否已经被打开,适用于BLOB、CLOB和BFILE类型 --如果LOB已经被打开,则返回1,否则返回0 DECLARE src_lob clob; begin src_lob:='中国,中国,伟大的中国'; if dbms_lob.isopen(src_lob)=0 then dbms_lob.open(src_lob,1); end if; dbms_lob.close(src_lob); end; --函数ISTEMPORARY --用于确定LOB定位符是否为临时LOB declare src_lob clob; begin if dbms_lob.istemporary(src_lob) = 1 then dbms_output.put_line('已经是临时LOB'); else dbms_output.put_line('临时LOB需要建立'); dbms_lob.createtemporary(src_lob,true); end if; dbms_lob.freetemporary(src_lob); end; --过程LOADFROMFILE --用于将BFILE的部分或者全部内容复制到目标LOB变量(CLOB或者BLOB)中 --注意:当使用该过程将BFILE数据装载到CLOB中时,不会进行字符集转换,因此要确保BFILE数据与数据库具有相同字符集,否则装载后的数据为乱码 DECLARE src_lob bfile; dest_lob clob; amount int; begin src_lob:=bfilename('TESTDIR','1.txt'); dbms_lob.createtemporary(dest_lob,true); dbms_lob.fileopen(src_lob,0); amount:=dbms_lob.getlength(src_lob); dbms_output.put_line('amount:'||amount); dbms_lob.loadfromfile(dest_lob,src_lob,amount); dbms_lob.fileclose(src_lob); dbms_lob.freetemporary(dest_lob); end; --过程LOADBLOBFROMFILE --用于将BFILE数据装载到BLOB中,并且在装载后可以取得新的偏移位置 DECLARE src_lob bfile; dest_lob blob; amount int; src_offset int:=1; dest_offset int:=1; begin src_lob:=bfilename('TESTDIR','1.txt'); dbms_lob.createtemporary(dest_lob,true); dbms_lob.fileopen(src_lob,0); amount:=dbms_lob.getlength(src_lob); dbms_lob.loadblobfromfile(dest_lob,src_lob,amount,dest_offset,src_offset); dbms_lob.fileclose(src_lob); dbms_lob.freetemporary(dest_lob); dbms_output.put_line('新的偏移位置:'||dest_offset); end; --过程LOADCLOBFROMFILE --用于将BFILE数据装载到CLOB中,当使用该过程装载数据到CLOB中时,可以指定字符集ID号,并进行字符集转换。 --因此,建议在装载BFILE数据到CLOB中时使用该过程 DECLARE src_lob bfile; dest_lob clob; amount int; src_offset int:=1; dest_offset int:=1; csid int:=0; lc int:=0; waring int; begin src_lob:=bfilename('TESTDIR','1.txt'); dbms_lob.createtemporary(dest_lob,true); dbms_lob.fileopen(src_lob,0); amount:=dbms_lob.getlength(src_lob); dbms_lob.loadclobfromfile(dest_lob,src_lob,amount,dest_offset,src_offset,csid,lc,waring); dbms_lob.fileclose(src_lob); dbms_output.put_line(dest_lob); dbms_lob.freetemporary(dest_lob); end; --过程OPEN --用于在打开LOB时指定LOB的读写模式:只读(dbms_lob.lob_readonly)、读写(dbms_lob.lob_readwrite) DECLARE src_lob clob; v1 varchar2(100):='中华人民共和国'; amount int; begin amount:=length(v1); dbms_lob.createtemporary(src_lob,true); dbms_lob.open(src_lob,dbms_lob.lob_readwrite); dbms_lob.write(src_lob,amount,1,v1); dbms_lob.close(src_lob); dbms_output.put_line(src_lob); dbms_lob.freetemporary(src_lob); end; --过程READ --用于将LOB数据读取到绊缓冲区中,不仅适用于BLOB和CLOB,也适用于BFILE DECLARE src_lob clob:='伟大的中国'; amount int; buffer varchar2(200); offset int:=1; begin amount:=dbms_lob.getlength(src_lob); dbms_lob.open(src_lob,dbms_lob.lob_readonly); dbms_lob.read(src_lob,amount,offset,buffer); dbms_output.put_line(buffer); dbms_lob.close(src_lob); end; --函数SUBSTR --用于返回LOB中从指定位置开始的部分内容,不仅适用于BLOB和CLOB,也适用于BFILE DECLARE src_lob clob:='中国,中国,伟大的中国'; amount int; v1 varchar2(200); offset int; begin amount:=10; offset:=4; v1:=dbms_lob.substr(src_lob,amount,offset); dbms_output.put_line(v1); end; --过程TRIM --用于截断LOB内容到指定长度,只适用于BLOB和CLOB,不适用于BFILE DECLARE src_lob clob:='中国,中国,伟大的中国'; amount int; begin amount:=5; dbms_lob.trim(src_lob,amount); dbms_output.put_line(src_lob); end; --过程WRITE --用于将缓冲区数据写入到LOB中的特定位置,只适用于BLOB和CLOB,而不适用于BFILE DECLARE src_lob clob:='我的祖国'; amount int; offset int; buffer varchar2(100):=',伟大的中国'; begin offset:=dbms_lob.getlength(src_lob)+1; amount:=length(buffer); dbms_lob.write(src_lob,amount,offset,buffer); dbms_output.put_line(src_lob); end; --过程WRITEAPPEND --用于将缓冲区数据写入到LOB尾部,只适用于BLOB和CLOB,而不适用于BFILE DECLARE src_lob clob:='我的祖国'; amount int; buffer varchar2(100):=',伟大的中国'; begin amount:=length(buffer); dbms_lob.writeappend(src_lob,amount,buffer); dbms_output.put_line(src_lob); end; --访问LOB --访问CLOB --建立包含CLOB列的表 CREATE TABLE lob_example1(id number(6) primary key,name varchar2(10),resume clob); --初始化CLOB列 insert into lob_example1 values(1,'王鸣',empty_clob()); insert into lob_example1 values(2,'马丽',empty_clob()); commit; select * from lob_example1; --更新CLOB列的数据 DECLARE lob_loc CLOB; text varchar2(200); amount int; offset int; begin select resume into lob_loc from lob_example1 where id=&id for update; offset:=DBMS_LOB.getlength(lob_loc)+1; text:='&resume'; amount:=length(text); dbms_lob.write(lob_loc,amount,offset,text); commit; end; select * from lob_example1; --读取CLOB列的内容 --第6个字符开始的所有字符 DECLARE lob_loc clob; buffer varchar2(200); amount int; offset int; BEGIN SELECT resume into lob_loc from lob_example1 where id=&id; offset:=6; amount:=dbms_lob.getlength(lob_loc); dbms_lob.read(lob_loc,amount,offset,buffer); dbms_output.put_line(buffer); END; --将文本文件内容写入到CLOB列 DECLARE lobloc CLOB; fileloc bfile; amount int; src_offset int:=1; dest_offset int:=1; csid int:=0; lc int:=0; warning int; BEGIN fileloc:=bfilename('TESTDIR','马丽.txt'); DBMS_LOB.fileopen(fileloc,0); amount:=dbms_lob.getlength(fileloc); select resume into lobloc from lob_example1 where id=2 for update; dbms_lob.loadclobfromfile(lobloc,fileloc,amount,dest_offset,src_offset,csid,lc,warning); dbms_lob.fileclose(fileloc); commit; END; select * from lob_example1; --将CLOB列内容写入到文本文件 --下面将RESUME列的内容写入到文本文件d:\testDir\a.txt中为例,说明将CLOB列的内容写入到文本文件的方法 DECLARE lobloc clob; amount int; offset int:=1; buffer varchar2(2000); handle utl_file.file_type; begin select resume into lobloc from lob_example1 where id=&id; amount:=dbms_lob.getlength(lobloc); dbms_lob.read(lobloc,amount,offset,buffer); handle:=utl_file.fopen('TESTDIR','a.txt','w',2000); utl_file.put_line(handle,buffer); utl_file.fclose(handle); end; --访问BLOB --建立包含BLOB列的表 --当在表中定义存放大批量二进制数据(例如图形/图象数据)的列时,应该选择BLOB类型 CREATE TABLE lob_example2(id number(6) primary key,name varchar2(10),photo blob); --初始化BLOB列 INSERT INTO lob_example2 values(1,'王鸣',empty_blob()); insert into lob_example2 values(2,'马丽',empty_blob()); commit; select * from lob_example2; --将二进制文件内容写入BLOB列 DECLARE lobloc blob; fileloc bfile; amount int; src_offset int:=1; dest_offset int:=1; begin select photo into lobloc from lob_example2 where id=&id for update; fileloc:=bfilename('TESTDIR','&filename'); dbms_lob.fileopen(fileloc,0); amount:=dbms_lob.getlength(fileloc); dbms_lob.loadblobfromfile(lobloc,fileloc,amount,dest_offset,src_offset); dbms_lob.fileclose(fileloc); commit; end; --读取BLOB列数据 --因为BLOB列中存放着二进制数据,所以当读取其数据时应该使用RAW变量接收其数据 --读取BLOB列的数据可以使用包DBMS_LOB的过程READ来完成 declare lobloc blob; buffer raw(20000); amount int; offset int:=1; begin select photo into lobloc from lob_example2 where id=&id; amount:=dbms_lob.getlength(lobloc); dbms_output.put_line(amount); dbms_lob.read(lobloc,amount,offset,buffer); end; select * from lob_example2; --将BLOB列的内容写入到二进制文件 DECLARE lobloc blob; amount int; offset int:=1; buffer raw(2000); handle utl_file.file_type; begin select photo into lobloc from lob_example2 where id=&id; amount:=dbms_lob.getlength(lobloc); dbms_lob.read(lobloc,amount,offset,buffer); handle:=utl_file.fopen('TESTDIR','a.bmp','w',1000); utl_file.put_raw(handle,buffer); utl_file.fclose(handle); end; --访问BFILE --建立包含BFILE列的表 CREATE TABLE lob_example3(id number(6) primary key,name varchar2(10),resume bfile); --初始化BFILE列 insert into lob_example3 values(1,'王鸣',bfilename('TESTDIR','王鸣.jpg')); insert into lob_example3 values(2,'马丽',bfilename('TESTDIR','马丽.jpg')); commit; select * from lob_example3; --读取BFILE列的内容 DECLARE buffer RAW(2000); amount int; offset int; lobloc bfile; begin select resume into lobloc from lob_example3 where id=&id; dbms_lob.fileopen(lobloc,0); amount:=dbms_lob.getlength(lobloc); offset:=1; dbms_lob.read(lobloc,amount,offset,buffer); dbms_lob.fileclose(lobloc); end;