看下使用方法:
 
ORACLE中LOB字段的使用和维护 
--------------------------------------------------------------------------------
摘要:本文通过实例介绍了在ORACLE数据库中通过DBMS_LOB包使用和维护LOB数据类型的基本方法。 
关键词:ORACLE  DBMS_LOB  LOB  维护  
    中图分类号:TP31  
1、引言  
随着社会的发展,在现代信息系统的开发中,需要存储的已不仅仅是简单的文字信息,同时还包括一些图片和音像资料或者是超长的文本。比如开发一套旅游信息系统,每一个景点都有丰富的图片、音像资料和大量的文字介绍。这就要求后台数据库要有存储这些数据的能力。ORACLE公司在其Oracle8i中通过提供LOB字段实现了该功能。 
为了便于读者的理解,我们先介绍一些基本的概念: 
在ORACLE数据库中,LOB(Large Objects—大对象)是用来存储大量的二进制和文本数据的一种数据类型(一个LOB字段可存储可多达4GB的数据)。目前,它又分为两种类型:内部LOB和外部LOB。内部LOB将数据以字节流的形式存储在数据库的内部。因而,内部LOB的许多操作都可以参与事务,也可以像处理普通数据一样对其进行备份和恢复操作。Oracle8i支持三种类型的内部LOB:BLOB(二进制数据)、CLOB(单字节字符数据)、NCLOB(多字节国家字符数据)。其中CLOB和NCLOB类型适用于存储超长的文本数据,BLOB字段适用于存储大量的二进制数据,如图像、视频、音频等。目前,Oracle8i只支持一种外部LOB类型,即BFILE类型。在数据库内,该类型仅存储数据在操作系统中的位置信息,而数据的实体以外部文件的形式存在于操作系统的文件系统中。因而,该类型所表示的数据是只读的,不参与事务。该类型可帮助用户管理大量的由外部程序访问的文件。 
为了方便下文的叙述,我们假定使用如下语句在数据库中创建了一张表。 
CREATE TABLE view_sites_info 
   (  
site_id       NUMBER(3), 
      audio          BLOB  DEFAULT empty_blob(), 
      document   CLOB  DEFAULT empty_clob(), 
video_file   BFILE  DEFAULT NULL, 
constraint PK_TAB_view_sites_info primary key (site_id) 
);
2、LOB的使用和维护 
ORACL提供了多种使用和维护LOB的方式,如使用PL/SQL DBMS_LOB包、调用OCI(Oracle Call Interface)、使用Proc * C/C++、使用JDBC等。其中最为方便有效的是使用PL/SQL调用DBMS_LOB包,本文就将介绍该方法。 
在Oracle中,存储在LOB中数据称为LOB的值,如使用Select 对某一LOB字段进行选择,则返回的不是LOB的值,而是该LOB字段的定位器(可以理解为指向LOB值的指针)。如执行如下的SQL语句: 
DELCARE 
       AUDIO_INFO  BLOB; 
BENGIN 
       SELECT audio INTO AUDIO_INFO FROM view_sites_info 
       WHERE site_id=100; 
END; 

存储在AUDIO_INFO变量中的就是LOB定位器,而不是LOB的值。而要对某一LOB的值进行访问和维护操作,必需通过其定位器来进行。DBMS_LOB包中提供的所有函数和过程都以LOB定位器作为参数。 
2.1内部LOB 
DBMS_LOB包中主要提供了以下几个过程供用户对内部LOB字段进行维护。 
APPEND()           将源LOB中的内容加到目的LOB中 
COPY()            从源LOB中复制数据到目的LOB 
ERASE()                   删除LOB中全部或部分内容 
TRIM()                     将LOB值减少到指定的长度 
WRITE()                   向LOB 中写入数据 
COMPARE()        比较两个同种数据类型的LOB的部分或全部值是否相同 
GETLENGTH()              获取LOB的长度 
READ()                     从LOB中读出数据 
下面我们以最为常用的读和写为例详细介绍这些过程的用法。 
首先介绍一下写过程。该过程的语法为: 
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: 指定写操作的缓冲区 
下面的代码就是运用该过程向LOB字段写入数据的示例。 
DECLARE 
     lobloc 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; 
   / 
需要特别指出的是: 
I.            在调用写过程前一定要使用SELECT语句检索到定位器且用 FOR UPDATE 子句锁定行,否则不能更新LOB; 
II.         写过程从offset指定的位置开始,向LOB中写入长度为amount的数据,原LOB中在这个范围内的任何数据都将被覆盖。 
III.       缓冲区的最大容量为32767字节,因此在写入大量数据时需多次调用该过程。 
   
下面再来介绍一下读过程: 
该过程的语法为: 
PROCEDURE READ ( 
     lob_loc   IN    BLOB, 
     amount    IN OUT  BINARY_INTEGER, 
     offset    IN    INTEGER, 
     buffer    OUT   RAW); 
   PROCEDURE READ ( 
     lob_loc   IN    CLOB     CHARACTER SET ANY_CS, 
     amount    IN OUT  BINARY_INTEGER, 
     offset    IN    INTEGER, 
     buffer    OUT   VARCHAR2 CHARACTER SET lob_loc%CHARSET); 
各参数的含义为: 
       lob_loc:要读取的LOB定位器 
       amount:要读取的字节数 
        offset:开始读取操作的偏移量 
       buffer: 存储读操作结果的缓冲区 
下面的代码演示了如何使用该过程读取LOB字段中的数据: 
   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; 
   /

解决方案 »

  1.   

    SQL> create table b (a clob);Table created.SQL> desc a
     Name                            Null?    Type
     ------------------------------- -------- ----
     A                                        VARCHAR2(10)SQL> select * from a;A
    ----------6SQL> insert into b select a from a;2 rows created.使用这个方法转花,然后把原来的表DROP掉,在建立回来,明白?
      

  2.   

    支持楼上的方法,可以试试。
    不过你可以查oracle的函数集,看可否用函数来实现
    数据类型转换
      

  3.   

    SQL> create table c(name varchar2(10));alteTable createdSQL> alter table c modify (name clob);alter table c modify (name clob)ORA-22858: 数据类型的更改无效建义新建一个字段吧
    把记录插入过去
    再删除旧字段