操作BLOB、CLOB、BFILE

摘要:
BLOB二进制大对象。CLOB字符类型的大型对象。要存储单字节块、多字节固定宽度和多字节可变宽度数据BFILETheBFILEDatatype,可以访问Oracle数据库外所有系统中恢复的二进制文件LOB。ABFILE列属性测试或ABFILE定位器,用于服务器文件系统上的点或二进制文件。位置或目录名和文件名oracle数据库可以通过bfile类型访问存储在操作系统上的二进制文件。您可以使用BFILENAME功能在不影响设置的情况下更改BFILE的文件名和路径。通过bfilename内置函数设置bfile类型的值,该函数有两个参数,即目录和文件名。二进制文件LOB不参与事务,并且不可恢复。相反,运行系统提供了完整性和持久性。尽管您的运行系统可能对其进行最大限制,但二进制文件数据最多可以达到264-1字节。数据库管理员必须确保存在外部文件,并且Oracle进程具有对文件的操作系统读取权限。BFILE数据类型启用对大型二进制文件的只读支持。您不能修改或复制这些文件。Oracle提供API以访问文件数据。用于访问文件数据的主要接口是DBMS_ LOBpackage和OracleCallInterface。bfile指向的操作系统文件的操作不由数据库事务管理。操作系统负责一致性和持久性。bfile可以处理的文件大小为2^64-1字节。因此,bfile文件大小的限制通常来自操作系统级别。

BFILE        二进制文件,存储在数据库外的操作系统文件,只读的。把此文件当二进制处理。
BLOB        二进制大对象。存储在数据库里的大对象,一般是图像声音等文件。
CLOB        字符型大对象。一般存储大数量文本信息。存储单字节,固定宽度的数据。
NCLOB        字节字符大对象。存储单字节大块,多字节固定宽度,多字节变宽度数据


BFILE

       The BFILE data type enables access to binary file LOBs that are stored in file systems outside Oracle Database. A BFILE column or attribute stores a BFILE locator, which serves as a pointer to a binary file on the server file system. The locator maintains the directory name and the filename.

        通过bfile类型,oracle数据库可以访问存储在操作系统上的二进制文件。我们可以认为在bfile中存放的是指向操作系统文件的指针。使用bfile必须首先创建directory,并具有相应的权限。
        You can change the filename and path of a BFILE without affecting the base table by using the BFILENAME function. 

        通过bfilename内置函数设置bfile类型的值,该函数具有两个参数,即directory和filename。
        Binary file LOBs do not participate in transactions and are not recoverable. Rather, the underlying operating system provides file integrity and durability. BFILE data can be up to 264-1 bytes, although your operating system may impose restrictions on this
maximum.The database administrator must ensure that the external file exists and that Oracle processes have operating system read permissions on the file.The BFILE data type enables read-only support of large binary files. You cannot modify or replicate such a file. Oracle provides APIs to access file data. The primary interfaces that you use to access file data are the DBMS_LOB package and Oracle Call Interface (OCI).
        对bfile指向的操作系统文件的操作,不被数据库事务管理,有操作系统来负责一致性和持久性,bfile可以处理的文件大小为2^64-1个字节,因此对bfile文件大小的限制往往来自操作系统层面。对于bfile指向的文件,数据库具有只读权限,不可以编辑和复制。我们主要通过DBMS_LOB包来管理和操作bfile类型数据。
        

[oracle@oadata dir1]$ pwd
/home/oracle/oradir/dir1
[oracle@oadata dir1]$ ls
1.txt  2.txt
[oracle@oadata dir1]$ cat 1.txt
1
2
3
4
5
6
[oracle@oadata dir1]$ cat 2.txt
a
b
c
d
[oracle@oadata dir1]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on 星期六 10月 12 11:58:08 2013

Copyright (c) 1982, 2011, Oracle.  All rights reserved.


连接到: 
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> create direcotry dir1 as '/home/oracle/oradir/dir1';
create direcotry dir1 as '/home/oracle/oradir/dir1'
       *
第 1 行出现错误:
ORA-00901: 无效 CREATE 命令


SQL> create directory dir1 as '/home/oracle/oradir/dir1';

目录已创建。

SQL> grant read,write on directory dir1 to easy;

授权成功。

SQL> conn easy/jodezhu
已连接。
SQL> show user
USER 为 "EASY"
SQL> create table tab_bfile (id number,bf bfile);

表已创建。

SQL> insert into tab_bfile values(1,bfilename('DIR1','1.txt'));

已创建 1 行。

SQL> insert into tab_bfile values(2,bfilename('DIR1','2.txt'));

已创建 1 行。

SQL> commit;

提交完成。

SQL> select * from tab_bfile;

	ID
----------
BF
----------------------------------------------------------------------------------------------------
	 1
bfilename('DIR1', '1.txt')

	 2
bfilename('DIR1', '2.txt')


SQL> set serveroutput on
DECLARE
  r tab_bfile%rowtype;
  CURSOR c
  IS
    SELECT id,bf FROM tab_bfile;
  AMOUNT INTEGER := 100;
  OFFSET INTEGER := 1;
  OUTRAW VARCHAR2(100);
BEGIN
  OPEN c;
  LOOP
    FETCH c INTO r;
    EXIT
  WHEN c%notfound;
    dbms_output.put_line(r.id);
    dbms_lob.open(r.bf,DBMS_LOB.LOB_READONLY);
    DBMS_LOb.READ(r.bf,amount,offset,outraw);
    dbms_output.put_line(outraw);
    dbms_lob.close(r.bf);
  END LOOP;
 21  END;
 22  /
1
310A320A330A340A350A360A
2
610A620A630A640A

PL/SQL 过程已成功完成。

SQL> 


          bfile类型在使用之前,必须要先打开。


BLOBCLOBNCLOB

        blobclob clob称为内部lob(bfile称为外部lob),其大小限制为2^32-1与所在表空间数据块大小乘积,大概范围在8T到128T,因此多数情况下,我们不必担心存储上限的问题。blob类型存储的是二进制流数据,而clob和nclob存储的是大规模的字符数据,在clob中按照数据库的字符集存储,而在nclob中按照数据库的国家字符集存储。内部lob由于存储在数据库内部,因此参与数据库的事务处理,在发送错误时可以进行回滚处理。可以通过plsql dbms_lob包或者oci接口来处理lob数据。

对lob数据的处理,可以不用在open/close函数对之间运行,此时,伴随着对lob的处理,会及时更新相应的索引,这可能会影响效率。当我们将其放在open/close对中时,则在close时,对索引进行更新。open/close必须成对出现   

        注意:

        It is an error to commit the transaction before closing all opened LOBs that were  opened by the transaction. When the error is returned, the openness of the open LOBs is discarded, but the transaction is successfully committed. Hence, all the changes made to the LOB and non-LOB data in the transaction are committed, but the domain and function-based indexes are not updated. If this happens, you should rebuild the functional and domain indexes on the LOB column. 

        在提交事务之前,一定要调用close函数关闭文件指针,否则虽然lob数据可以提交成功,但是对应的索引却无法更新。

 

        注意:在clob或者nclob中存储数据时,如果数据库字符集或者国家字符集为变长字符集,那么在clob或者nclob中,按照USC2格式存储数据,这一点会在下面的代码的验证

        向lob类型中装载数据可以使用LOADFROMFILE、LOADCLOBFROMFILE、LOADBLOBFROMFILE。LOADFROMFILE可以装载bfile,blob、clob、nclob类型的数据,载入时按照二进制流的格式处理,不会进行字符集的处理。LOADBLOBFROMFILE用于装载blob数据,其用法同loadfromfile相同。LOAFCLOBFROMFILE用来装载clob或者nclob数据,该函数可以进行字符集的转换。

           首先,看一下LOADFROMFILE的用法。

          

[easy@easy dir1]$ ls -l
总用量 12
-rw-r--r-- 1 easy oinstall 4 10月 13 06:49 gbk.txt   //创建了三个文本文件,其编码格式为gbk  utf-8  usc2  
-rw-r--r-- 1 easy oinstall 4 10月 13 06:51 usc2.txt  //关于linux下字符集的转换,请参照:http://blog.csdn.net/yidian815/article/details/12650431
-rw-r--r-- 1 easy oinstall 6 10月 13 07:09 utf8.txt     
[easy@easy dir1]$ 

SQL> select * from tab_clob;  //表tab_clob包含两个字段,id  number,cb clob

未选定行

SQL> DECLARE
  ucb CLOB; --对应utf编码
  gcb CLOB; --对应gbk编码
  uscb CLOB; --对应usc2编码
  ubf bfile;
  gbf bfile;
  usbf bfile;
BEGIN
  ubf := bfilename('DIR1','utf8.txt');
  gbf := bfilename('DIR1','gbk.txt');
  usbf := bfilename('DIR1','usc2.txt');
  DELETE FROM tab_clob;
  INSERT INTO tab_clob VALUES
    (3,empty_clob()
    ) RETURNING cb INTO ucb;
  INSERT INTO tab_clob VALUES
    (4,empty_clob()
    ) RETURNING cb INTO gcb;
  INSERT INTO tab_clob VALUES
    (5,empty_clob()
    ) RETURNING cb INTO uscb;
  dbms_lob.fileopen(ubf);
  dbms_lob.fileopen(gbf);
  dbms_lob.fileopen(usbf);
  dbms_lob.loadfromfile(ucb, ubf, dbms_lob.getlength(ubf) );
  dbms_lob.loadfromfile(gcb, gbf, dbms_lob.getlength(gbf) );
  dbms_lob.loadfromfile(uscb, usbf, dbms_lob.getlength(usbf) );
  dbms_lob.fileclose(ubf);
  dbms_lob.fileclose(gbf);
  dbms_lob.fileclose(usbf);
  COMMIT;
END;
/

SQL> l
  1* select * from tab_clob
SQL> /

    ID CB
---------- --------------------
         3 �鏧芹
         4 틗뗣
         5 易点                           //只有id=5的记录,显示正确,这是因为数据库字符集(UTF-8)是变长字符集,因此clob以usc2格式存储数据,
                                          //而loadfromfile,以二进制流格式处理数据,不进行字符集转换,所以只有usc2.txt文件可以正常显示

   下面再来看看loadclobfromfile的用法

SQL>DECLARE
  ucb CLOB;
  gcb CLOB;
  ubf bfile;
  gbf bfile;
  uamount INTEGER;
  udoff   INTEGER := 1;
  usoff   INTEGER := 1;
  ucs     NUMBER  := 871;    //操作系统文件的字符集id,可以通过NLS_CHARSET_ID 来查询,871代表utf-8
  ucon    INTEGER :=0;
  uw      INTEGER :=0;
  gamount INTEGER;
  gdoff   INTEGER := 1;
  gsoff   INTEGER := 1;
  gcs     NUMBER  := 852;    //852 代表zhs16gbk
  gcon    INTEGER :=0;
  gw      INTEGER :=0;
BEGIN
  ubf := bfilename('DIR1','utf8.txt');
  gbf := bfilename('DIR1','gbk.txt');
  DELETE FROM tab_clob;
  
  INSERT INTO tab_clob VALUES
    (1,empty_clob()
    ) RETURNING cb INTO ucb;
    
  INSERT INTO tab_clob VALUES
    (2,empty_clob()
    ) RETURNING cb INTO gcb;
    
  dbms_lob.fileopen(ubf);
  dbms_lob.fileopen(gbf);
  dbms_lob.loadclobfromfile(ucb, ubf, dbms_lob.getlength(ubf), udoff, usoff, ucs, ucon, uw );
  dbms_lob.loadclobfromfile(gcb,gbf,dbms_lob.getlength(gbf), gdoff, gsoff, gcs, gcon, gw );
  dbms_lob.fileclose(ubf);
  dbms_lob.fileclose(gbf);
  COMMIT;
END;
/

SQL> /

    ID CB
---------- --------------------
         1 易点
         2 易点



从这里,可以看出,在装载clob和nclob时,我们最好使用LOADCLOBFROMFILE,以避免乱码问题。






免责声明:文章转载自《操作BLOB、CLOB、BFILE》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇项目原型设计VASP+Phono3py计算声子linewidth下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Oracle的dual

1.dual 确实是一张表.是一张只有一个字段,一行记录的表(虚拟表). 2.习惯上,我们称之为'伪表'.因为他不存储主题数据.3. 他的存在,是为了操作上的方便.因为select 都是要有特定对象的.如:select * from mytable ;select * from myview;等等. 4.dual 是由 sql.bsq 建立的。每个data...

oracle中导出表的结构和数据

在linux环境上: exp user_name/password@//ip_address:1521/service_name file=aa.sql tables=(table_name); 或者: exp user_name/password@tns_name file=aa.sql tables=(table_name); 在window环境上:...

oracle导入及导出dmp文件

导出数据库步骤: exp 用户名/密码@实例名 file=导出的dmp文件存放路径(绝对路径) log=导出日志存放路径(建议记录log文件,方便后续核实数据是否完整导出和导入) 导入数据库步骤: 1.首先创建指定用户的表空间(可忽略) 实例: create tablespace BP_DATA datafile 'E:APPADMINISTRATOROR...

oracle 监听启动问题 Instance "orcl", status UNKNOWN, has 1 handler(s) for this service...

相关说明: Oracle11g64位软件的安装位置为/u01/app/oracle/product/11.2.0/dbhome_1 ,数据库名为默认的orcl,Linux虚拟机的HOSTNAME为master。 一、修改listener.ora文件内容 命令:[oracle@gpdb ~]$ vi /u01/app/oracle/product/11.2....

Oracle实例解析:编码与字符集

字符集:人们根据需要把某些字符收集到一处,并赋以名称,于是便有了某某字符集。 编码:当前面收集的工作完成以后,为了让只认识数字的“愚蠢”的计算机也能够存储字符,人们不得不为集合里的每一个字符分配”身份证号码”,这就是编码,从此,终于可以以存储编码的方式在计算机中存储字符了。 在字符集与编码世界的漫漫历史长河里(伪),出现过若干个让计算机工作者们如雷贯耳的名...

利用Python操作MySQL数据库

前言 在工作中,我们需要经常对数据库进行操作,比如 Oracle、MySQL、SQL Sever 等,今天我们就学习如何利用Python来操作 MySQL 数据库。 本人环境:Python 3.7.0 、MySQL 5.7 安装第三方库 使用Python来操作MySQL,需要用到 PyMySQL 这个第三方库,具体安装如下: pip install PyM...