µ±ǰλÖ㺠´úÂëÃÔ >> SQL >> PL/SQL块定义部åˆ?LOB类型
  Ïêϸ½â¾ö·½°¸

PL/SQL块定义部åˆ?LOB类型

Èȶȣº330   ·¢²¼ʱ¼䣺2016-05-05 12:19:28.0
PL/SQL块定义部åˆ?-LOB类型

在Oracle的早期版æœ?¸­,使用LONG å’?LONG RAW 类型存放大数æ�??‚从8i版本å¼?始,Oracle引入了LOB数据类型,并且Oracle建è?å¼?发人员尽量去使用LOB类型而不去使ç”?LONG å’?LONG RAW 。LOB类型和LONG、LONG RAW类型相比有几ä¸?¸�同的地方。å?ï¼?br>1、LOB(除了NCOLB)å�?»¥作为对象类型的一ä¸?±ž性,但LONG类型不可以ã??br>2、LOB的最大å?¼是4G,è?ŒLONGå�?œ‰2Gã€?br>3、LOBæ”?Œ�随机访问数据,但LONGå�?”¯持顺序è?é—???br>    LOB包括内部LOB和å?部LOB,其ä¸?†…部LOB(BLOB CLOB NLOB)的数æ�?­˜放到数据库中,è?Œå?部LOB(BFILE)的数æ�?­˜放在操作系统的文件中。具体è?明å?下:
BLOB:存放二进制格式的数据,å?:图像ã?�音频ã?�è?频等ã€?br>CLOB:存放数据库字符集格式的字符数æ�?¼Œ如:大的文本数据ã€?br>NCLOB:存放Unicode字ç?集的字ç?数据ã€?br>BFILE:存放指向操作系统文件的指针,并且该文件即å�?»¥æ˜?–‡æœ?–‡件,也可以是二进制文件ã?‚当我们访问该类型所表示的列时,å�?ƒ½读取数据,不能修改ã??br>  
ä¸?、理解什么是LOB定位器和LOB数据
    LOB数据æ˜?ˆ‘ä»?­˜入到数据库中的å?¼,而LOB 定位å™?æ˜?“�作这些å?¼的指针。当我们想è?取或者修改LOB数据时,我们必须先è?获取LOB 定位å™?,然后é?š过LOB定位器才能è?取或者修改LOB数据,下面的示例能å?å¸?Š©我们更好的理è§?OB数据和LOB定位å™?¼š
DECLARE
picLOB BLOB;
BEGIN
   --假定 picColumn列是BLOB类型
  SELECT picColumn INTO picLOB FROM myTable WHERE ID=10;
END;
    当SELECT INTOè¯?�¥执è?完之后, picLOB变量将è?赋å?¼,但是 picLOB变量的å?¼不是LOB数据,è?Œ是LOB数据的定位器。è?想获取LOB数据,我ä»?¿…须å?定位器进行操作,Oracle中DBMS_LOB包里的很多函数和过程都可以å?定位器进行操作,如下ï¼?br>APPEND()ï¼?将源LOBä¸?š„内å?加到ç›?š„LOBä¸?br>COPY() :从源LOBä¸??制数æ�?ˆ°ç›?š„LOB
ERASE()ï¼?删除LOBä¸?…¨部或部分内å?
TRIM()ï¼?将LOB值减少到指定的长åº?br>WRITE()ï¼?向LOB ä¸?†™入数æ�?br>COMPARE()ï¼?比较两个同ç?数据类型的LOB的部分或全部值是否相å�?br>GETLENGTH()ï¼?获取LOB的长åº?br>READ()ï¼?从LOBä¸??出数æ�?/p>

二ã?�使用CLOB数据类型
示例1:创建带有CLOB数据类型的表,并插入数据
CREATE TABLE CLOB_TABLE
(
  id NUMBER(3) PRIMARY KEY,
  remark CLOB    --remark:å?æ³?br>);
INSERT INTO CLOB_TABLE(id) VALUES(1);  --remark列没有定位器,并且没有数æ�?br>INSERT INTO CLOB_TABLE VALUES(2,'IDä¸?的å?注信æ�?);  --remark列有定位å™?¼Œ并且有数æ�?br>INSERT INTO CLOB_TABLE VALUES(3,empty_clob());--remarkå�?œ‰定位å™?¼Œ但是没有数据

æ£?索定位器的å?¼:
DECLARE
myLob CLOB;
BEGIN
  SELECT remark INTO myLob FROM CLOB_TABLE WHERE id=___ ;
  IF myLob IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('myLob IS NULL ');
  ELSE
    DBMS_OUTPUT.PUT_LINE(myLob );
  END IF;
END;
当下划线å¡?…¥1时,结果如下ï¼?br>myLob IS NULL
当下划线å¡?…¥2时,结果如下ï¼?-打印出定位器æ‰?指向的数æ�?br>IDä¸?的å?注信æ�?br>当下划线å¡?…¥3时,没有打印出信æ�???/p>

ä¿?”¹idä¸?的remark列,使其具有定位å™?¼š
UPDATE CLOB_TABLE SET remark=empty_clob() WHERE id=1;
这时再调用以上的代码块,这æ?没有打印出信æ�???/p>

示例2:向CLOB列追加数æ�?br>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 );  --获取追加文本的长åº?br>  offset:=DBMS_LOB.GETLENGTH (myLob)+1;  --获取定位器引用的LOB数据çš?长度
  DBMS_LOB.WRITE (myLob,amount,offset, buffer );-- 向CLOB列追加数æ�?¼Œ每æ?æœ?大追åŠ?2767字节。è?注意必须先存在定位器才能追加数据,否则会出现invalid LOB locator specified: ORA-22275错è?ã€?br>  --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 WHERE id=2;
  amount:=15;
  offset:=3;
  --从LOB数据ä¸?š„ç¬?¸‰ä¸?­—符开始è?取共读取15ä¸?­—符放入到text变量
  DBMS_LOB.READ(myLob,amount,offset,text);
  DBMS_OUTPUT.PUT_LINE(text);
END;

三ã?�使用BFile数据类型
    BFile类型不存放文件实际数æ�?¼Œ而是存放文件的指针,文件的数æ�?­˜储在操作系统的文件系统上,并且我ä»?�ª能é?š过BFile类型读取文件的数æ�?¼Œ不能ä¿?”¹ã€?br>示例1:创建ScottDirç›?½•,并授予scott用户读权é™?br>CREATE DIRECTORY ScottDir AS 'E:\ScottDir'; --注意此è?句并不会在操作系统上创建文件å¤?br>GRANT READ ON DIRECTORY ScottDir TO scott;

示例2:创建含有BFile数据类型的列,并插入数据
CREATE TABLE BFILE_TABLE
(
   id NUMBER PRIMARY KEY,
   remark  BFILE
);
插入数据ï¼?br>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è¯?�¥直接查看其内容ã??/p>

示例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 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;

四ã?�使用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','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;

  Ïà¹ؽâ¾ö·½°¸