【问题标题】:Oracle database: How to read a BLOB?Oracle 数据库:如何读取 BLOB?
【发布时间】:2011-08-06 15:29:42
【问题描述】:

我正在使用 Oracle 数据库,我想读取 BLOB 的内容。我该怎么做呢?

当我执行一个简单的选择语句时,它只返回“(BLOB)”(不带引号)。如何阅读实际内容?

【问题讨论】:

  • 我在该线程中尝试了查询并收到以下错误消息:“ORA-06502: PL/SQL: numeric or value error: raw variable length too long ORA-06512: at line 1 06502. 00000 - "PL/SQL: 数字或数值错误%s" *原因:*操作:"
  • 在二进制 Lob(字符 LOB)中可能包含无法像 VARCHAR 那样表示的值。在 PL\SQL 中,一个 VARCHAR 变量可以包含 32767 字节,也要注意数据库字符集。
  • 为什么不使用可以显示 BLOB 列内容的 GUI 客户端(假设您使用的是 SQL*Plus)

标签: sql oracle blob


【解决方案1】:

您可以使用UTL_RAW.CAST_TO_RAW(UTL_RAW.CAST_TO_VARCHAR2()) 转储十六进制值。

SELECT b FROM foo;
-- (BLOB)

SELECT UTL_RAW.CAST_TO_RAW(UTL_RAW.CAST_TO_VARCHAR2(b))
FROM foo;
-- 1F8B080087CDC1520003F348CDC9C9D75128CF2FCA49D1E30200D7BBCDFC0E000000

这很方便,因为这是用于插入 BLOB 列的相同格式:

CREATE GLOBAL TEMPORARY TABLE foo (
    b BLOB);
INSERT INTO foo VALUES ('1f8b080087cdc1520003f348cdc9c9d75128cf2fca49d1e30200d7bbcdfc0e000000');

DESC foo;
-- Name Null Type 
-- ---- ---- ---- 
-- B        BLOB 

但是,在某个点(2000 字节?),相应的十六进制字符串超过了 Oracle 的最大字符串长度。如果您需要处理这种情况,则必须将 How do I get textual contents from BLOB in Oracle SQLdocumentation for DMBS_LOB.SUBSTR 结合起来,以采用更复杂的方法,让您可以查看 BLOB 的子字符串。

【讨论】:

    【解决方案2】:

    SQL Developer 可以将 blob 显示为图像(至少它适用于 jpeg)。在数据视图中,双击 BLOB 字段以获取“铅笔”图标。单击铅笔会出现一个对话框,允许您选择“查看为图像”复选框。

    【讨论】:

      【解决方案3】:

      如果内容不是太大,也可以使用

      SELECT CAST ( <blobfield> AS RAW( <maxFieldLength> ) ) FROM <table>;
      

      SELECT DUMP ( CAST ( <blobfield> AS RAW( <maxFieldLength> ) ) ) FROM <table>;
      

      这将显示十六进制值。

      【讨论】:

        【解决方案4】:

        如果您使用 Oracle 本地数据提供程序而不是 Microsoft 驱动程序,那么您可以获得所有字段类型

        Dim cn As New Oracle.DataAccess.Client.OracleConnection
        Dim cm As New Oracle.DataAccess.Client.OracleCommand
        Dim dr As Oracle.DataAccess.Client.OracleDataReader
        

        连接字符串不需要 Provider 值,因此您可以使用以下内容:

        "Data Source=myOracle;UserID=Me;Password=secret"
        

        打开连接:

        cn.ConnectionString = "Data Source=myOracle;UserID=Me;Password=secret"
        cn.Open()
        

        附加命令并设置Sql语句

        cm.Connection = cn
        cm.CommandText = strCommand
        

        设置获取大小。我使用 4000 因为它和 varchar 一样大

        cm.InitialLONGFetchSize = 4000
        

        启动阅读器并遍历记录/列

        dr = cm.ExecuteReader
        
        Do while dr.read()
            strMyLongString = dr(i)
        Loop
        

        如果您首先确定列中的数据类型,您可以更具体地读取,例如 dr.GetOracleString(i) dr.GetOracleClob(i) 等。如果您正在读取 LONG 数据类型,那么简单的 dr(i)dr.GetOracleString(i) 可以正常工作。关键是确保 InitialLONGFetchSize 对于数据类型足够大。另请注意,本机驱动程序不支持数据读取器的 CommandBehavior.SequentialAccess,但您不需要它,而且 LONG 字段甚至不必是 select 语句中的最后一个字段。

        【讨论】:

          【解决方案5】:

          您使用什么客户端? .Net、Java、Ruby、SQLPLUS、SQL 开发者?你在哪里写了那个简单的选择语句?

          还有为什么要读取blob的内容,一个blob包含二进制数据所以数据是不可读的。如果要存储文本而不是二进制内容,则应使用 clob 而不是 blob。

          我建议你下载 SQL DEVELOPER: http://www.oracle.com/technetwork/developer-tools/sql-developer/overview/index.html 。使用 SQL DEVELOPER,您可以查看内容。

          【讨论】:

          • 有趣。我正在使用 SQL Developer,但它没有向我显示内容。它只给我看了“(BLOB)”
          • 可能与SQL Developer版本有关。似乎只在最新版本上添加了 BLOB 下载/可视化功能。
          【解决方案6】:

          如果您有兴趣从BLOB 获取纯文本(正文部分),您可以使用CTX_DOC package

          例如,CTX_DOC.FILTER 过程可以“生成纯文本或 HTML 版本的文档”。请注意,CTX_DOC.FILTER 需要在 BLOB 列上建立索引。如果您不希望这样,您可以改用 CTX_DOC.POLICY_FILTER 过程,它不需要索引。

          【讨论】:

            猜你喜欢
            • 2021-06-24
            • 2014-10-02
            • 2016-07-24
            • 2012-04-07
            • 2011-03-31
            • 2020-06-26
            • 2017-06-14
            • 2012-01-16
            • 2020-03-20
            相关资源
            最近更新 更多