LOB类型列主要是用来存储大量数据的数据库字段,最大可以存储4G字节的非结构化数据。

一、LOB数据类型分类

1、按存储数据的类型分:

①字符类型:
   CLOB:存储大量 单字节 字符数据。
   NLOB:存储定宽 多字节 字符数据。
  ②二进制类型:
   BLOB:存储较大无结构的二进制数据。
  ③二进制文件类型:
   BFILE:将二进制文件存储在数据库外部的操作系统文件中。存放文件路径。

2、按存储方式分:

①存储在内部表空间:
    CLOB,NLOB和BLOB
   ②指向外部操作系统文件:
    BFILE

一、Null LOBs与Empty LOBs

DECLARE
some_clob CLOB;
BEGIN
IF some_clob IS NULL THEN
dbms_output.put_line('a'); --NULL 表示该 LOB 字段或变量中连 LOB 指针都没有
ELSIF dbms_lob.getlength(some_clob) = 0 THEN
dbms_output.put_line('b'); --empty LOB 是指该 LOB 字段或变量中保存了一个 LOB 指针,但这个指针并没有指向任何 LOB 数据
ELSE
dbms_output.put_line('c'); --指针有实际内容
END IF;
END;

二、LOB写入

Blob数据不能象其它类型数据一样直接插入(INSERT)。插入前必须先插入一个空的Blob对象,BLOB类型的空对象为EMPTY_BLOB(),之后通过SELECT命令查询得到先前插入的记录并锁定,继而将空对象修改为所要插入的Blob对象。

当获取到一个可用的 LOB 指针(定位器)后,就可以通过该指针写入 LOB 数据了。有两种写入数据的系统函数:
* DBMS_LOB.WRITE :将数据随机地写入 LOB 中。
* DBMS_LOB.WRITEAPPEND :从 LOB 的最后开始写入数据。

运用dbms_lob包用dbms_lob.write()写入只能存储32k以下的图片。

注意:这里并不需要使用 UPDATE 来更新列 falls_myclob,因为这个 LOB 指针并没有发生变化,我们只是将数据写入它所指向的位置。

declare
myclob clob;
amount binary_integer;
offset integer;
first_direction varchar2(100);
more_myclob varchar2(500);
begin
--删除所有“munining Falls”的现有行,然后
delete from waterfalls where falls_name = 'Munising Falls'; insert into waterfalls (falls_name, falls_myclob) values ('Munising Falls', EMPTY_CLOB()); --使用EMPTY_CLOB()插入新行来创建LOB定位器
select falls_myclob into myclob from waterfalls where falls_name = 'Munising Falls'; --检索由前面的INSERT语句创建的LOB定位器
--或直接
INSERT into waterfalls(falls_name, falls_myclob) values('Munising Falls' EMPTY_CLOB()); returning falls_myclob into myclob; DBMS_LOB.OPEN(myclob, DBMS_LOB.LOB_READWRITE); --打开LOB;不是严格必要的,但是最好打开/关闭lob。 first_direction := 'Follow I-75 across the Mackinac Bridge.';
amount := LENGTH(first_direction); --要写的字符数
offset := 1; --开始写CLOB的第一个字符
DBMS_LOB.WRITE(myclob, amount, offset, first_direction); --使用DBMS_LOB。开始写 more_myclob := ' Take US-2 west from St. Ignace to Blaney Park.' || ' From Seney, take M-28 west to Munising.'; --使用DBMS_LOB.WRITEAPPEND添加更多的myclob
DBMS_LOB.WRITEAPPEND(myclob, LENGTH(more_myclob), more_myclob); more_myclob := ' In front of the paper mill, turn right on H-58.' || ' Sand Point Road.'; --添加更多的myclob
DBMS_LOB.WRITEAPPEND(myclob, LENGTH(more_myclob), more_myclob); DBMS_LOB.CLOSE(myclob); --关闭LOB,就完成了。
end;

三、LOB读取

使用系统函数 DBMS_LOB.READ( ) 来读取 LOB 中的数据,当然,首先要得到这个 LOB 指针。比如读取 CLOB 数据,应该指定字符串的偏移量(offset),从指定的偏移量的位置开始读取数据。
CLOB 的第一个字符的偏移量是1;也需要指定读取的字符串长度。如果这个 CLOB 数据太大,应该多次读取数据。对于 BLOB 数据,也是这样处理,唯一的区别就是它是按字节存储的。

DBMS_LOB.READ 中的第二个参数 chars_read_1,是 IN OUT 参数。

调用时按照该参数指定的长度来读取数据,读取完毕后,将其更新为实际读取的字符(字节)长度。

当读取后,该参数的值比你原来的值小,则说明已经读取到 LOB 的末尾了。

declare
myclob clob;
myclob_1 varchar2(300);
myclob_2 varchar2(300);
chars_read_1 binary_integer;
chars_read_2 binary_integer;
offset integer;
begin
select falls_myclob into myclob from waterfalls where falls_name = 'Munising Falls'; --检索之前插入的LOB定位器
offset := 1; --从第一个字符开始阅读
chars_read_1 := 229; --尝试读取myclob的229个字符时,chars_read_1将使用实际读取的字符数进行更新
DBMS_LOB.READ(myclob, chars_read_1, offset, myclob_1); if chars_read_1 = 229 then --如果读取229个字符,则更新偏移量并尝试读取255个字符。
offset := offset + chars_read_1;
chars_read_2 := 255;
DBMS_LOB.READ(myclob, chars_read_2, offset, myclob_2);
else
chars_read_2 := 0;
myclob_2 := '';
end if; DBMS_OUTPUT.PUT_LINE('Characters read = ' || TO_CHAR(chars_read_1 + chars_read_2)); --显示读取的字符总数
DBMS_OUTPUT.PUT_LINE(myclob_1); --显示myclob
DBMS_OUTPUT.PUT_LINE(myclob_2);
end;

四、BFile文件大对象(存储在操作系统文件中的数据)

PL/SQL中的Bfile只能读取Bfile数据,而不能写入。

BLOB,CLOB,NCLOB 存储在数据库内,而 BFILE 存储在数据库外。BFILE 和其他三种大字段类型相比,BFILE 有以下三点不同:

  1. BFILE 的数据是存储在操作系统文件中的,而不是在数据库中;
  2. BFILE 数据不参与事务处理,也就是说,BFILE 数据的改变不能被提交和回滚(但 BFILE 指针的改变是可以提交或回滚的);
  3. 从 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 
end

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 大对象处理的更多相关文章

  1. [转帖]Oracle数据库lob大对象数据类型字段总结,值得收藏

    Oracle数据库lob大对象数据类型字段总结,值得收藏 原创 波波说运维 2019-07-11 00:02:00 https://www.toutiao.com/i67108943269703357 ...

  2. JavaEE JDBC 读写LOB大对象

    JDBC 读写LOB大对象 @author ixenos LOB 除了数字.字符串和日期之外,许多数据库还可以存储大对象,例如图片或其他数据, 在SQL中,二进制(字节型)大对象称为BLOB,字符型大 ...

  3. oracle对大对象类型操作:blob,clob,nclob

     1.基本介绍 Oracle和plsql都支持lob(large object) 类型,用来存储大数量数据,如图像文件,声音文件等.Oracle 9i realse2支持存储最大为4g的数据,or ...

  4. oracle之 Oracle LOB 详解

    一.  官方说明 Oracle 11gR2 文档: LOB Storage http://download.oracle.com/docs/cd/E11882_01/appdev.112/e18294 ...

  5. Oracle数据库中的大对象(LOB)数据类型介绍

    一.LOB数据类型的介绍 大对象(LOB)数据类型允许我们保存和操作非结构化和半结构化数据,如文档.图形图像.视频片段.声音文件和XML文件等.DMBS_LOB 包被设计用于操作 LOB 数据类型.从 ...

  6. ORACLE DBA_OBJECTS视图中OBJECT_TYPE为LOB的对象查看

    在ORACLE数据库中,DBA_OBJECTS视图中OBJECT_TYPE为LOB的对象是什么东西呢?其实OBJECT_TYPE为LOB就是大对象(LOB),它指那些用来存储大量数据的数据库字段.下面 ...

  7. Spring 让 LOB 数据操作变得简单易行,LOB 代表大对象数据,包括 BLOB 和 CLOB 两种类型

    转自:https://www.ibm.com/developerworks/cn/java/j-lo-spring-lob/index.html 概述 LOB 代表大对象数据,包括 BLOB 和 CL ...

  8. ORACLE大对象存储

    --创建有大对象字段的一张表 create table test001 (       fname varchar2(50),       content blob )  select * from ...

  9. 大对象数据LOB的应用(Day_10)

    当你有永不放弃的精神,全力以赴的态度,你会惊叹自己也能创造奇迹! LOB数据类型概述 由于于无结构的数据往往都是大型的,存储量非常大,而LOB(large object)类型主要用来支持无结构的大型数 ...

随机推荐

  1. eNSP模拟器OSPF单区域配置

    实验拓扑图如下 下一步对终端设备与路由器的端口进行基本的ip设置 配置完成后要注意检查是否有小错误,不然会对后面的测试带来麻烦.在进行基础配置的时候一定要细心细心细心. 下一步我们就要进行OSPF的配 ...

  2. 微信小程序之一:动态添加view(view包含picker,input)

    <view wx:for="{{array}}" wx:key="this" class="borderContainer"> ...

  3. [转帖]一文尽懂 USB4

    一文尽懂 USB4 https://www.ithome.com/0/451/062.htm 今年 3 月份,USB Promoter Group(领导小组)首次发布了 USB4 规范,即下一代 US ...

  4. Python进阶:metaclass谈

    metaclass 的超越变形特性有什么用? 来看yaml的实例: import yaml class Monster(yaml.YAMLObject): yaml_tag = u'!Monster' ...

  5. VNC的使用

    1. 安装 rpm -ivh tigervnc-server--.el6.x86_64.rpm 如果rpm安装时发现有依赖,建议直接使用yum安装,轻松解决依赖问题: yum install tige ...

  6. try except 异常捕获的方法、断言的使用

    except as e中的'e'的作用总结 - 2puT - CSDN博客 Python使用try except处理程序异常的三种常用方法分析 Python3和Python2 异常处理except的不 ...

  7. SPA项目首页导航+左侧菜单

    Mock.js是个啥 前后端分离之后,前端迫切需要一种机制,不再需要依赖后端接口开发,而今天的主角mockjs就可以做到这一点 Mock.js是一个模拟数据的生成器,用来帮助前端调试开发.进行前后端的 ...

  8. LOJ3049 [十二省联考2019] 字符串问题 【后缀自动机】【倍增】【拓扑排序】

    题目分析: 建出后缀自动机,然后把A串用倍增定位到后缀自动机上,再把B串用倍增定位到后缀自动机上. SAM上每个点上的A串根据长度从小到大排序,建点,依次连边. 再对于SAM上面每个点,连到儿子的边, ...

  9. The 2018 ACM-ICPC Asia Nanjing Regional Programming Contest

    A. Adrien and Austin 大意: $n$个石子, 编号$1$到$n$, 两人轮流操作, 每次删除$1$到$k$个编号连续的石子, 不能操作则输, 求最后胜负情况. 删除一段后变成两堆, ...

  10. Angular 学习笔记 immer 使用

    https://github.com/immerjs/immer#supported-object-types immer 是用来做 immutable 的. angular 的 change det ...