返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Oracle中大对象(LOB)处理方法
  • 633
分享到

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

2024-04-02 19:04:59 633人浏览 安东尼
摘要

目录一、LOB数据类型分类1、按存储数据的类型分2、按存储方式分3、Null LOBs与Empty LOBs二、LOB写入三、LOB读取四、BFile文件大对象(存储在操作系统文件中

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

--结束END--

本文标题: Oracle中大对象(LOB)处理方法

本文链接: https://lsjlt.com/news/148138.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Oracle中大对象(LOB)处理方法
    目录一、LOB数据类型分类1、按存储数据的类型分2、按存储方式分3、Null LOBs与Empty LOBs二、LOB写入三、LOB读取四、BFile文件大对象(存储在操作系统文件中...
    99+
    2024-04-02
  • ORACLE LOB 大对象处理
    LOB大对象处理:主要是用来存储大量数据的数据库字段,最大可以存储4G字节的非结构化数据。主要介绍字符类型和二进制文件类型LOB数据的存储,单独介绍二进制类型LOB数据的存储。 一.  Oracl...
    99+
    2024-04-02
  • 详解处理Java中的大对象的方法
    目录String中的substring集合大对象扩容保持合适的对象粒度Bitmap 把对象变小数据的冷热分离数据双写写入 MQ 分发使用 Binlog 同步思维发散小结本文我们将讲解...
    99+
    2024-04-02
  • 如何处理Java中的大对象
    这篇文章主要介绍“如何处理Java中的大对象”,在日常操作中,相信很多人在如何处理Java中的大对象问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何处理Java中的大对象”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-30
  • Java Stream对象并行处理方法parallel()
            Stream.parallel() 方法是 Java 8 中 Stream API 提供的一种并行处理方式。在处理大量数据或者耗时操作时,使用 Stream.parallel() 方法可以充分利用多核 CPU 的优势,提高程...
    99+
    2023-09-02
    java 开发语言
  • PDO中操作大数据对象的方法
    这篇文章主要介绍了PDO中操作大数据对象的方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。PDO操作大数据对象一般在数据库中,我们保存的都...
    99+
    2024-04-02
  • Python中如何处理大数据文件中的对象?
    在现代数据科学中,我们经常需要处理大型数据集。这些数据可能以多种格式存储,包括文本、CSV、JSON、数据库、图像和视频等。在这些数据集中,一些常见的数据类型是对象,如列表、元组、字典、类实例等。在本文中,我们将探讨如何在Python中处...
    99+
    2023-10-26
    对象 文件 大数据
  • JavaScript优雅处理对象的6种方法
    目录前言1、Object.freeze()2、Object.seal()3、Object.keys()4、Object.values()5、Object.create()6、Obje...
    99+
    2024-04-02
  • Oracle数据库失效对象处理
    近期对数据库进行巡检,发现数据库业务用户(非 SYS/Public)下存在失效对象。对失效对象进行分析,主要包括失效的视图、物化视图、函数、包、触发器等。思考:基于以下原因,建议对失效对象进行处理:1、通过失效的对象,可能能够反推发现业务...
    99+
    2015-09-11
    Oracle数据库失效对象处理
  • 如何在Java中高效地处理大数据对象?
    在当今数据爆炸的时代,处理大数据已经成为了各行业都需要面对的问题。而在Java开发中,如何高效地处理大数据对象,也是一个需要解决的难题。本文将从以下几个方面为您详细介绍如何在Java中高效地处理大数据对象。 一、使用流式API Java 8...
    99+
    2023-10-12
    大数据 对象 numpy
  • Java中的对象编程算法:如何处理大量数组数据?
    在Java中,处理大量数组数据是一种常见的需求。无论是在数据分析、图像处理还是机器学习等领域,都需要高效地处理大量的数据。在这种情况下,使用对象编程算法能够有效地提高代码的可读性和可维护性,并且能够更快地处理大量数据。 本文将介绍Java...
    99+
    2023-10-31
    对象 编程算法 数组
  • Java如何应用于大数据处理中的对象管理?
    随着大数据时代的到来,数据的处理已经成为了人们日常工作中不可或缺的一部分。在大数据处理中,对象管理是非常重要的一环。Java作为一种优秀的编程语言,它在大数据处理中的对象管理方面也发挥了重要作用。本文将会详细介绍Java在大数据处理中的对...
    99+
    2023-10-12
    大数据 对象 numpy
  • 大数据处理中的Java对象管理和Numpy的数据处理技巧对比分析。
    大数据处理中的Java对象管理和Numpy的数据处理技巧对比分析 随着大数据时代的到来,数据处理技术也在不断地发展和进步。在数据处理过程中,Java和Numpy是两种非常流行的技术,它们在数据处理中都有着独特的优势和不足。本文将对Java对...
    99+
    2023-10-12
    大数据 对象 numpy
  • Numpy在大数据处理中的优势和Java的对象处理技巧对比分析?
    Numpy和Java都是在大数据处理中广泛使用的工具。Numpy是Python中的一个科学计算库,而Java则是一种面向对象的编程语言。本文将分析Numpy在大数据处理中的优势和Java的对象处理技巧,并对两者进行对比分析。 一、Numpy...
    99+
    2023-10-12
    大数据 对象 numpy
  • Java如何处理大数据中的对象操作问题?
    随着数据量的不断增大,Java在处理大数据中的对象操作问题上面也会遇到一些困难。本文将介绍Java中处理大数据中的对象操作问题,并提供一些代码示例。 一、使用缓存来优化对象操作 在处理大数据量时,Java中的对象操作会变得十分缓慢,因为内...
    99+
    2023-10-12
    大数据 对象 numpy
  • 如何利用Python处理大数据文件中的对象?
    随着数据量的快速增长,处理大数据已成为许多企业和组织所面临的最大挑战之一。Python语言因其简单易学、灵活和高效的特点,成为了处理大数据的首选语言之一。本文将介绍如何利用Python处理大数据文件中的对象,为读者提供一些实用的技巧和工具。...
    99+
    2023-10-26
    对象 文件 大数据
  • 如何在Go中处理对象?
    在Go语言中,对象是通过结构体来表示的。结构体是一种用户自定义的数据类型,它可以包含任意数量的变量和方法。在本文中,我们将探讨如何在Go中处理对象,并演示一些代码示例。 定义结构体 首先,我们需要定义一个结构体来表示对象。下面是一个简单的例...
    99+
    2023-06-19
    path 对象 编程算法
  • Java中如何处理Path对象?
    Path对象是Java中处理文件和目录路径的核心类之一,它提供了丰富的方法和功能,让我们能够轻松地操作文件和目录路径。在本文中,我们将介绍Java中如何处理Path对象,包括创建、访问、操作和处理Path对象。 一、创建Path对象 创建...
    99+
    2023-09-21
    path 对象 bash
  • Oracle数据库失效对象处理详情
    近期对数据库进行巡检,发现数据库业务用户(非 SYS/Public)下存在失效对象。对失效对象进行分析,主要包括失效的视图、物化视图、函数、包、触发器等。 思考: 基于以下原因,建议...
    99+
    2024-04-02
  • JavaScript中方对象拷贝方法
    这篇文章主要讲解了“JavaScript中方对象拷贝方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript中方对象拷贝方法”吧! ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作