Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1703216
  • 博文数量: 136
  • 博客积分: 10021
  • 博客等级: 上将
  • 技术积分: 3261
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-22 11:26
文章分类

全部博文(136)

文章存档

2010年(1)

2009年(26)

2008年(109)

我的朋友

分类: Oracle

2008-06-06 15:18:27

我们先前介绍过,BLOB,CLOB,NCLOB 存储在数据库内,而 BFILE 存储在数据库外。和其他三种大字段类型相比,BFILE 有以下三点不同:
 
* BFILE 的数据是存储在操作系统文件中的,而不是在数据库中;
* BFILE 数据不参与事务处理,也就是说,BFILE 数据的改变不能被提交和回滚(但 BFILE 指针的改变是可以提交或回滚的);
* 从 PL/SQL 中,只能读取 BFILE 数据,而不能写入。必须得在数据库外先创建 BFILE 文件,再创建 BFILE 指针。
 
在 PL/SQL 中操作 BFILE,其实也是操作 LOB 指针。只是对于 BFILE 的指针来说,它指向的 BFILE 数据在数据库外。所以,一个 BFILE 列的两行,可以存储指向同一个文件的 BFILE 指针。
 
1. 创建
 
BFILE 指针由目录和文件名组成,将这两部分信息作为参数传入 BFILENAME 函数,该函数会返回一个 BFILE 指针。
 
例如,我要将存储于 D 盘中的图片 waterfall.gif 以 BFILE 的形式保存到数据库中:
 
D:\temp>dir wat*
 驱动器 D 中的卷是 D
 卷的序列号是 15C2-D261
 
 D:\temp 的目录
 
2008-06-06  11:08            56,073 waterfall.gif
               1 个文件         56,073 字节
               0 个目录  7,558,959,104 可用字节
 
那么首先,我应该创建一个目录:
 
SQL> create directory bfile_data as 'D:\temp';
 
目录已创建。
 
然后,通过很简单的调用 BFILENAME 函数,即可将 BIFLE 指针保存到表中:
 
SQL> DECLARE
  2     waterfall_picture BFILE;
  3  BEGIN
  4     --Invoke BFILENAME to create a BFILE locator
  5     waterfall_picture := BFILENAME('BFILE_DATA','waterfall.gif');
  6
  7     --Save our new locator in the waterfalls table
  8     INSERT INTO waterfalls (falls_name, falls_web_page)
  9        VALUES ('my waterfall',waterfall_picture);
 10  END;
 11  /
 
PL/SQL 过程已成功完成。
 
这里是可以提交和回滚的,因为这里发生改变的是 BFILE 指针,而不是 BFILE 数据。
 
一个 BFILE 指针只是简单地将目录和文件名联合在一块,而实际的目录和文件甚至可以不存在。所以,你可以创建一个目录,它实际指向的路径并不存在;再使用这个目录创建一个 BFILE 指针。很多时候,这种功能使得我们编程很方便。
 
2. 读取
 
BFILE 数据的读取,与我们前面介绍的其他 LOB 类型的读取方式是一样的。
 
SQL> DECLARE
  2     waterfall BFILE;
  3     piece RAW(60);
  4     amount BINARY_INTEGER := 60;
  5     offset INTEGER := 1;
  6  BEGIN
  7     --Retrieve the LOB locator
  8     SELECT falls_web_page
  9       INTO waterfall
 10       FROM waterfalls
 11      WHERE falls_name='my waterfall';
 12
 13     --Open the locator, read 60 bytes, and close the locator
 14     DBMS_LOB.OPEN(waterfall);
 15     DBMS_LOB.READ(waterfall, amount, 1, piece);
 16     DBMS_LOB.CLOSE(waterfall);
 17
 18     --Display results in hex
 19     DBMS_OUTPUT.PUT_LINE(RAWTOHEX(piece));
 20
 21     --Cast RAW results to a character string we can read
 22     --DBMS_OUTPUT.PUT_LINE(UTL_RAW.CAST_TO_VARCHAR2(piece));
 23  END;
 24  /
474946383961CF01320277003121FE1A536F6674776172653A204D6963726F736F6674204F666669
63650021F90401000000002C00000000CE013102
 
PL/SQL 过程已成功完成。
 
在一个会话中,可以打开的文件总数受参数 session_max_open_files 限制,该参数同时限制了使用其他方式打开的文件数(比如使用 UTL_FILE 包打开的文件数):
 
SQL> show parameter session_max
 
NAME                                 TYPE        VALUE
------------------------------------ ----------- -----
session_max_open_files               integer     10
 
 
在 Oracle 中,对 BFILE 数据只能做读操作。比如你用数码相机照了一些照片,并将它们上传到你的电脑上了。那么,你可以使用 BFILE 类型,在数据库中创建对应的 BFILE 指针,这样,你就可以在 PL/SQL 代码中访问它们了。
 
3. 从 BFILE 到 LOB
 
BFILE 提供了一种从数据库中访问文件系统中数据的方法。可能你想将这些数据保存到 BLOB 或 CLOB 字段中。从 Oracle9i Database Release 1 开始,可以使用系统函数 DBMS_LOB.LOADFROMBFILE 实现;从 Oracle9i Database Release 2 开始,又提供了两个函数
 
* DBMS_LOB.LOADCLOBFROMBFILE:从 BFILE 数据中获取 CLOB 数据(注意字符集的转换)。
 
* DBMS_LOB.LOADBLOBFROMBFILE:从 BFILE 数据中获取 BLOB 数据。功能和 DBMS_LOB.LOADFROMBFILE 一样,只是为了统一而提供的函数。
 
下面我们将图片 watarfall.gif 保存到 BLOB 列中:
 
SQL> DECLARE
  2    My_Falls_Directions BFILE := BFILENAME('BFILE_DATA','waterfall.gif');
  3    photo BLOB;
  4    destination_offset INTEGER := 1;
  5    source_offset INTEGER := 1;
  6    language_context INTEGER := DBMS_LOB.default_lang_ctx;
  7    warning_message INTEGER;
  8  BEGIN
  9    --Delete row for Tannery Falls, so this example
 10    --can run multiple times.
 11    DELETE FROM waterfalls WHERE falls_name='my waterfall';
 12
 13    --Insert a new row using EMPTY_BLOB(  ) to create a LOB locator
 14    INSERT INTO waterfalls
 15              (falls_name,FALLS_PHOTO)
 16       VALUES ('my waterfall',EMPTY_BLOB(  ));
 17
 18    --Retrieve the LOB locator created by the previous INSERT statement
 19    SELECT FALLS_PHOTO
 20      INTO photo
 21      FROM waterfalls
 22     WHERE falls_name='my waterfall';
 23
 24    --Open the target BLOB and the source BFILE
 25    DBMS_LOB.OPEN(photo, DBMS_LOB.LOB_READWRITE);
 26    DBMS_LOB.OPEN(My_Falls_Directions);
 27
 28    --Load the contents of the BFILE into the BLOB column
 29    DBMS_LOB.LOADBLOBFROMFILE(photo, My_Falls_Directions,
 30                              DBMS_LOB.LOBMAXSIZE,
 31                              destination_offset, source_offset);
 32
 33    --Close both LOBs
 34    DBMS_LOB.CLOSE(photo);
 35    DBMS_LOB.CLOSE(My_Falls_Directions);
 36  END;
 37  /
 
PL/SQL 过程已成功完成。
阅读(1343) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~