BLOB,CLOB,NCLOB 存储在数据库内,而 BFILE 存储在数据库外。BFILE 和其他三种大字段类型相比,BFILE 有以下三点不同:
- BFILE 的数据是存储在操作系统文件中的,而不是在数据库中;
- BFILE 数据不参与事务处理,也就是说,BFILE 数据的改变不能被提交和回滚(但 BFILE 指针的改变是可以提交或回滚的);
- 从 PL/SQL 中,只能读取 BFILE 数据,而不能写入。必须得在数据库外先创建 BFILE 文件,再创建 BFILE 指针。
在 PL/SQL 中操作 BFILE,其实也是操作 LOB 指针。只是对于 BFILE 的指针来说,它指向的 BFILE 数据在数据库外。
所以,一个 BFILE 列的两行,可以存储指向同一个文件的 BFILE 指针。
1. 创建
BFILE 指针由目录(Oracle服务器上)和文件名组成(而实际的目录和文件可以不存在),将这两部分信息作为参数传入 BFILENAME 函数,该函数会返回一个 BFILE 指针。
create directory BFILE_DATA as 'D:/temp'; declare waterfall_picture bfile; begin waterfall_picture := BFILENAME('BFILE_DATA','waterfall.gif'); --调用BFILENAME来创建BFILE定位器 insert into waterfalls (falls_name, falls_web_page) values ('my waterfall',waterfall_picture); --保存我们的新定位在waterfalls en
2. 读取
declare waterfall bfile; piece raw(60); amount binary_integer := 60; offset integer := 1; begin select falls_web_page into waterfall from waterfalls where falls_name='my waterfall'; --检索LOB定位器 DBMS_LOB.OPEN(waterfall); --打开定位器,读取60个字节,然后关闭定位器 DBMS_LOB.READ(waterfall, amount, 1, piece); DBMS_LOB.CLOSE(waterfall); DBMS_OUTPUT.PUT_LINE(RAWTOHEX(piece));--十六进制显示结果 --将原始结果转换为我们可以读取的字符串 --DBMS_OUTPUT.PUT_LINE(UTL_RAW.CAST_TO_VARCHAR2(piece)); end;
五、将文件系统数据库通过BFile导入到LOB字段中
BFILE 提供了一种从数据库中访问文件系统中数据的方法。可能你想将这些数据保存到 BLOB 或 CLOB 字段中。
可以使用系统函数实现:
- dbms_lob.loadfrombfile
- dbms_lob.loadclobfrombfile
- dbms_lob.loadblobfrombfile
下面我们将图片 watarfall.gif 保存到 BLOB 列中:
declare My_Falls_bfile bfile := BFILENAME('BFILE_DATA', 'waterfall.gif'); photo blob; destination_offset integer := 1; source_offset integer := 1; begin delete from waterfalls where falls_name = 'my waterfall'; --删除Tannery Falls的行,所以这个例子可以运行多次。 insert into waterfalls (falls_name, FALLS_PHOTO) values ('my waterfall', EMPTY_BLOB());--使用EMPTY_BLOB()插入新行来创建LOB定位器 select FALLS_PHOTO into photo from waterfalls where falls_name = 'my waterfall'; --检索由前面的INSERT语句创建的LOB定位器 DBMS_LOB.OPEN(photo, DBMS_LOB.LOB_READWRITE);--打开目标BLOB和源BFILE DBMS_LOB.OPEN(My_Falls_bfile); DBMS_LOB.LOADBLOBFROMFILE(photo, My_Falls_bfile, DBMS_LOB.LOBMAXSIZE, destination_offset, source_offset); --Load the contents of the BFILE into the BLOB column DBMS_LOB.CLOSE(photo); --关闭两个lob DBMS_LOB.CLOSE(My_Falls_bfile); end;
六、C#读写Oracle BOLB数据。
(1)写入数据到Orable Blob字段中。
首先要在BLob字段中插入一个Empty_blob(),才能写入下面的数据。
* 在调用此函数之前需要写插入一个字符串到 BLOB 中比如: * "CREATE TABLE tablewithlobs (a int, b BLOB, c CLOB, d NCLOB)"; * "INSERT INTO tablewithlobs values (1, 'AA', 'AAA', N'AAAA')"; * 否则程序会在 OracleLob tempLob = reader.GetOracleLob(0) 处出错。
写入:
conn.Open(); OracleCommand cmd = conn.CreateCommand(); OracleTransaction transaction = cmd.Connection.BeginTransaction(); // 利用事务处理(必须) cmd.Transaction = transaction; // 获得 OracleLob 指针 cmd.CommandText = "select fulls_myblob from waterfalls where fulls_name = 'myabc' FOR UPDATE"; using (OracleDataReader reader = cmd.ExecuteReader()) { reader.Read(); //Obtain the first row of data. OracleBlob tempLob = reader.GetOracleBlobForUpdate(0); //Obtain a LOB. FileStream fs = new FileStream("c:\\1.txt", FileMode.Open); // 将文件写入 BLOB 中 tempLob.BeginChunkWrite(); int length = 10485760; byte[] Buffer = new byte[length]; int i; while ((i = fs.Read(Buffer, 0, length)) > 0) { tempLob.Write(Buffer, 0, i); } fs.Close(); tempLob.EndChunkWrite(); cmd.Parameters.Clear(); } transaction.Commit(); // 提交事务 conn.Close();
(2)读取Oracle Blob到文件中。
conn.Open(); OracleCommand cmd = conn.CreateCommand(); OracleTransaction trans = cmd.Connection.BeginTransaction();// 利用事务处理(必须) cmd.Transaction = trans; // 获得 OracleLob 指针 string sql = "select fulls_myblob from waterfalls where fulls_name = 'myabc'"; cmd.CommandText = sql; OracleDataReader dr = cmd.ExecuteReader(); dr.Read(); OracleBlob tempLob = dr.GetOracleBlob(0); dr.Close(); // 读取 BLOB 中数据,写入到文件中 FileStream fs = new FileStream("c:\\1.txt", FileMode.Create); int length = 1048576; byte[] Buffer = new byte[length]; int i; while ((i = tempLob.Read(Buffer, 0, length)) > 0) { fs.Write(Buffer, 0, i); } fs.Close(); tempLob.Clone(); cmd.Parameters.Clear(); trans.Commit(); // 提交事务 conn.Close();
到此这篇关于Oracle中大对象(LOB)处理方法的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。