Oracle中大对象(LOB)处理方法

目录
  • 一、LOB数据类型分类
    • 1、按存储数据的类型分
    • 2、按存储方式分
    • 3、Null LOBs与Empty LOBs
  • 二、LOB写入
  • 三、LOB读取
  • 四、BFile文件大对象(存储在操作系统文件中的数据)
    • 1. 创建
    • 2. 读取
  • 五、将文件系统数据库通过BFile导入到LOB字段中
  • 六、C#读写Oracle BOLB数据。
    • (1)写入数据到Orable Blob字段中。
    • (2)读取Oracle Blob到文件中。

一、LOB数据类型分类

1、按存储数据的类型分

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

2、按存储方式分

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

3、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 有以下三点不同:

  • 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)处理方法的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 使用JDBC4.0操作Oracle中BLOB类型的数据方法

    在JDBC4.0推出后,它的从多的特性正在受到广泛地关注.下面通过本文给大家介绍JDBC4.0操作Oracle中BLOB类型的数据的方法. 需要的jar包 使用ojdbc6.jar 在/META-INF/MANIFEST.MF里可以看到Specification-Version: 4.0 建表 create sequence seq_blobmodel_id start with 1 increment by 1 nocache; create table blobmodel ( blobid

  • Oracle的CLOB大数据字段类型操作方法

    一.Oracle中的varchar2类型 我们在Oracle数据库存储的字符数据一般是用VARCHAR2.VARCHAR2既分PL/SQL Data Types中的变量类型,也分Oracle Database中的字段类型,不同场景的最大长度不同. 在Oracle Database中,VARCHAR2 字段类型,最大值为4000:PL/SQL中 VARCHAR2 变量类型,最大字节长度为32767. 当 VARCHAR2 容纳不下我们需要存储的信息时,就出来的Oracle的大数据类型LOB( La

  • Oracle 插入超4000字节的CLOB字段的处理方法

    在通过拼组sql语句来实现数据插入的应用中,我们很有可能会遇到需要插入大型数据的情况,例如,在oracle中需要插入字节数超过4000的字段内容时,我们如果通过简单的拼组sql语句来实现插入,显然就会出现问题,而在sql server中却没有这个限制,个人尝试了26w个字符的sql语句在sql server2005中执行,依旧可以插入数据,但是在oracle中插入超过4000个字符的内容则会报异常. 下面就此问题的解决办法,做一下小结: 我们可以通过创建单独的OracleCommand来进行指定

  • 向Oracle数据库的CLOB属性插入数据报字符串过长错误

    今天在项目中向数据库的CLOB属性插入一段篇文章(1000~2000)字就会报一个字符串过长的错误. 网上说用流来处理,没有这么做.这像是一个Bug,只要把插入的数据,默认扩充到2000以上就ok了. 下面是这段代码: if((temp.length()>=1000)&&(temp.length()<=2000)){ temp=StringUtils.rightPad(temp, 2008); } 使用StringUtils的rightPad方法使没超过2000的部分,在右边自

  • 深入浅析mybatis oracle BLOB类型字段保存与读取

    一.BLOB字段 BLOB是指二进制大对象也就是英文Binary Large Object的所写,而CLOB是指大字符对象也就是英文Character Large Object的所写.其中BLOB是用来存储大量二进制数据的:CLOB用来存储大量文本数据.BLOB通常用来保存图片.文件等二进制类型的数据. 二.使用mybatis操作blob 1.表结构如下: create table BLOB_FIELD ( ID VARCHAR2(64 BYTE) not null, TAB_NAME VARC

  • ORACLE批量导入图片到BLOB字段代码示例

    要插入图片的表不是固定的,而且是批量插入很多张,还要考虑到因为图片的文件名错误,修改后要再次插入,此时应避免已经插入的重复执行操作, 浪费时间. 所以就选择先用一张临时表来暂时保存从文件系统读取的照片,用DBMS_LOB的方法来处理. 第一步:创建一个数据库可以访问的目录(注意:这个目录是数据库服务器上的目录,不是客户机上的) -- Create directory create or replace directory 图片目录 as 'E:\照片'; 第二步:将图片文件放入刚建好的目录下面,

  • oracle数据库中如何处理clob字段方法介绍

    在知识库的建立的时候,用普通VARCHAR2存放文章是显然不够的,只有区区4000的字节,放不了多少字, 而CLOB数据类型,则能最多存放8G的数据.但是这个字段处理起来有比较多的特殊性,记录一下. 插入: 直接写在SQL里面是不行的,一来SQL脚本有字符数限制,而来文章内容包含许多特殊字符,如换行,引号, 之类的东西,很麻烦.网上流行通用做法是先插入一个空CLOB字段,用empty_clob()方法来创建空字段,如: 复制代码 代码如下: INSERT INTO T_TOPIC(TOPIC_I

  • oracle中读写blob字段的问题解析

    LOB类型分为BLOB和CLOB两种:BLOB即二进制大型对像(Binary Large Object),适用于存贮非文本的字节流数据(如程序.图像.影音等).而CLOB,即字符型大型对像(Character Large Object),则与字符集相关,适于存贮文本型的数据(如歷史档案.大部头著作等). 下面以程序实例说明通过JDBC操纵Oracle数据库LOB类型字段的几种情况. 先建立如下两个测试用的数据库表,Power Designer PD模型如下: 建表SQL语句为:CREATE TA

  • Oracle中大对象(LOB)处理方法

    目录 一.LOB数据类型分类 1.按存储数据的类型分 2.按存储方式分 3.Null LOBs与Empty LOBs 二.LOB写入 三.LOB读取 四.BFile文件大对象(存储在操作系统文件中的数据) 1. 创建 2. 读取 五.将文件系统数据库通过BFile导入到LOB字段中 六.C#读写Oracle BOLB数据. (1)写入数据到Orable Blob字段中. (2)读取Oracle Blob到文件中. 一.LOB数据类型分类 1.按存储数据的类型分 字符类型: CLOB:存储大量 单

  • 数据转换冲突及转换过程中大对象的处理

    数据转换冲突及处理 数据转换冲突: 在数据转换过程中,要想实现严格的等价转换是比较困难的.必须要确定两种模型中所存在的各种语法和语义上的冲突,这些冲突可能包括: (1)命名冲突:源数据源的标识符可能是目的数据源中的保留字. (2)格式冲突:同一种数据类型可能有不同的表示方法和语义差异. (3)结构冲突:如果两种DBMS之间的数据定义模型不同,如为关系模型和层次模型,则需要重新定义实体属性和联系,以防止属性或联系信息的丢失. (4)类型冲突:不同数据库的同一种数据类型存在精度之间的差异. (5)其

  • Oracle存储过程、包、方法使用总结(推荐)

    Oracle存储过程.包.方法使用总结,具体代码如示: /** *@author:zhengwei *@date:2017-04-28 *@desc:存储过程用法总结 */ CREATE OR REPLACE PROCEDURE MYPROCEDURE(P_ID IN VARCHAR, P_STATUS OUT VARCHAR) --P_ID为输入参数 ,P_STATUS为输出参数 AS ---变量声明 T_STATUS VARCHAR2(20); T_ID NUMBER; V_POSTYPE

  • 检测oracle数据库坏块的方法

    检测oracle数据库坏块的办法: 1.使用DBV(DB File Verify)工具; 2.使用RMAN(Recovery Manager)工具; DBV(DB File Verify)工具: 外部命令,物理介质数据结构完整性检查: 只能用于数据文件(offline或online),不支持控制文件和重做日志文件的块检查: 也可以验证备份文件(rman的copy命令备份或操作系统CP命令备份): 进入盘符,然后执行以下脚本: D:\app\Administrator\oradata\orcl>d

  • LINUX下Oracle数据导入导出的方法详解

    本文讲述了LINUX下Oracle数据导入导出的方法.分享给大家供大家参考,具体如下: 一. 导出工具 exp 1. 它是操作系统下一个可执行的文件 存放目录/ORACLE_HOME/bin exp导出工具将数据库中数据备份压缩成一个二进制系统文件.可以在不同OS间迁移   它有三种模式: a.  用户模式: 导出用户所有对象以及对象中的数据: b.  表模式: 导出用户所有表或者指定的表: c.  整个数据库: 导出数据库中所有对象. 2. 导出工具exp交互式命令行方式的使用的例子: $ex

  • MySQL中大对象的多版本并发控制详解

    MySQL 8.0:InnoDB中大对象的MVCC 在本文中,我将解释MySQL InnoDB存储引擎中大对象(LOB)设计的多版本并发控制(MVCC) . MySQL 8.0有一个新功能,允许用户部分更新大型对象,包括JSON文档 . 使用此部分更新功能,当LOB部分更新时,MVCC对LOB的工作方式已发生变化. 对于正常更新(完整更新),MVCC将像以前的版本一样工作. 让我们看一下MVCC在不涉及部分更新时的工作原理,然后考虑对LOB进行部分更新的用例. MVCC 常规更新 我使用术语常规

  • 查看postgresql数据库用户系统权限、对象权限的方法

    PostgreSQL简介 PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS),是以加州大学计算机系开发的POSTGRES,4.2版本为基础的对象关系型数据库管理系统.POSTGRES的许多领先概念只是在比较迟的时候才出现在商业网站数据库中.PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询.外键.触发器.视图.事务完整性.多版本并发控制等.同样,PostgreSQL也可以用许多方法扩展,例如通过增加新的数据类型.函数.操作符

  • mybatis使用oracle进行添加数据的方法

    本次博主主要进行oralce数据库开发,好久不用oracle,有很多知识点也忘的差不多了,本次主要是复习一下工作中主要使用的一些sql语句编写: 查询 查询语句都是正常的,但是需要注意的是oracle数据库在查询的时候,表名使用别名的时候,请不要使用as关键字,只有mysql数据库才可以使用,oracle只支持字段名别名可以使用as关键字. 增加 添加数据的时候,我们后台很可能使用到添加后的主键id,此时也跟mysql不一样,mybatis只要配置一下insert属性就可以了,比如: <inse

  • Docker容器迁移Oracle到MySQL的实现方法

    目录 ️ 1. 创建专用网络 ️ 2. Oracle 12C部署 2.1 镜像下载 2.2 容器创建 2.3 创建业务用户 2.4 监听启动 ️ 3. MySQL8部署 3.1 容器创建 3.2 参数设置 3.3 登陆MySQL ️ 4. kettle迁移Oracle到MySQL 4.1 部署kettle 4.2 Oracle端数据校验 4.3 迁移Oracle到MySQL 4.4 迁移后MySQL数据验证 前言 Kettle是开源的 [TEL] 工具,JVAV编写,可以运行在多个平台,使用时有

  • Linux下修改Oracle监听地址的方法

    lisenter.ora 目录在 /opt/oracle/11g/network/admin LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = 10.1.111.123)(PORT = 1521)) ) ) ADR_BASE_LISTENER = /opt/oracle tnsnames.o

随机推荐