LOB(5)— BFILE

我们先前 介绍过,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 过程已成功完成。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值