ǰλã >> 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;

  ؽ