125

我试图从 SQL 控制台查看 Oracle BLOB 中的内容。

我知道它包含大量文本,我只想查看文本,但以下查询仅表明该字段中有一个 BLOB:

select BLOB_FIELD from TABLE_WITH_BLOB where ID = '<row id>';

我得到的结果并不完全符合我的预期:

    BLOB_FIELD
    ----------------------
    oracle.sql.BLOB@1c4ada9

那么我可以做什么样的魔法咒语来将 BLOB 变成它的文本表示?

PS:我只是想从 SQL 控制台(Eclipse 数据工具)查看 BLOB 的内容,而不是在代码中使用它。

4

12 回答 12

153

首先,您可能希望将文本存储在 CLOB/NCLOB 列中,而不是为二进制数据设计的 BLOB(顺便说一下,您的查询可以使用 CLOB)。

以下查询将让您看到 blob 中文本的前 32767 个字符(最多),前提是所有字符集都兼容(存储在 BLOB 中的文本的原始 CS,用于 VARCHAR2 的数据库的 CS):

select utl_raw.cast_to_varchar2(dbms_lob.substr(BLOB_FIELD)) from TABLE_WITH_BLOB where ID = '<row id>';
于 2009-05-06T09:36:15.630 回答
24

SQL Developer 也提供了这个功能:

双击结果网格单元格,然后单击编辑:

在此处输入图像描述

然后在弹出窗口的右上角,“查看为文本”(您甚至可以看到图像..)

在此处输入图像描述

就是这样!

在此处输入图像描述

于 2018-12-07T15:12:25.887 回答
16

您可以使用下面的 SQL 从表中读取 BLOB 字段。

SELECT DBMS_LOB.SUBSTR(BLOB_FIELD_NAME) FROM TABLE_NAME;
于 2014-12-23T10:57:40.990 回答
8

如果您想在文本中搜索,而不是查看它,这可行:

with unzipped_text as (
  select
    my_id
    ,utl_compress.lz_uncompress(my_compressed_blob) as my_blob
  from my_table
  where my_id='MY_ID'
)
select * from unzipped_text
where dbms_lob.instr(my_blob, utl_raw.cast_to_raw('MY_SEARCH_STRING'))>0;
于 2014-02-18T17:13:47.647 回答
6

使用此 SQL 获取 BLOB 的前 2000 个字符。

SELECT utl_raw.cast_to_varchar2(dbms_lob.substr(<YOUR_BLOB_FIELD>,2000,1)) FROM <YOUR_TABLE>;

注意:这是因为,Oracle 将无法处理长度超过 2000 的 BLOB 转换。

于 2020-01-15T14:25:32.187 回答
3

谷仓的回答对我有用,因为我的列没有被压缩。快速而肮脏的解决方案:

select * from my_table
where dbms_lob.instr(my_UNcompressed_blob, utl_raw.cast_to_raw('MY_SEARCH_STRING'))>0;
于 2014-04-11T17:13:04.850 回答
3

我为此苦苦挣扎了一段时间,并实施了 PL/SQL 解决方案,但后来意识到在 Toad 中,您只需双击结果网格单元格,它就会打开一个包含文本内容的编辑器。(我在蟾蜍 v11 上)

在此处输入图像描述

于 2014-05-13T13:06:59.737 回答
2

我可以使用 TO_CLOB ( docs )让它工作:

select 
  to_clob(BLOB_FIELD)
from 
  TABLE_WITH_BLOB 
where 
  ID = '<row id>';

这在 Oracle 19c 中适用于我,其 BLOB 字段大于 VARCHAR 限制。我得到可读的文本(来自一个持有 JSON 的 BLOB)

于 2021-07-20T16:51:24.540 回答
1

你可以试试这个:

SELECT TO_CHAR(dbms_lob.substr(BLOB_FIELD, 3900)) FROM TABLE_WITH_BLOB;

但是,它将被限制为 4000 字节

于 2018-07-13T19:49:26.240 回答
1

如果您的文本使用 DEFLATE 算法在 blob 内被压缩并且非常大,您可以使用此函数来读取它

CREATE OR REPLACE PACKAGE read_gzipped_entity_package AS

FUNCTION read_entity(entity_id IN VARCHAR2)
  RETURN VARCHAR2;

END read_gzipped_entity_package;
/

CREATE OR REPLACE PACKAGE BODY read_gzipped_entity_package IS

FUNCTION read_entity(entity_id IN VARCHAR2) RETURN VARCHAR2
IS
    l_blob              BLOB;
    l_blob_length       NUMBER;
    l_amount            BINARY_INTEGER := 10000; -- must be <= ~32765.
    l_offset            INTEGER := 1;
    l_buffer            RAW(20000);
    l_text_buffer       VARCHAR2(32767);
BEGIN
    -- Get uncompressed BLOB
    SELECT UTL_COMPRESS.LZ_UNCOMPRESS(COMPRESSED_BLOB_COLUMN_NAME)
    INTO   l_blob
    FROM   TABLE_NAME
    WHERE  ID = entity_id;

    -- Figure out how long the BLOB is.
    l_blob_length := DBMS_LOB.GETLENGTH(l_blob);

    -- We'll loop through the BLOB as many times as necessary to
    -- get all its data.
    FOR i IN 1..CEIL(l_blob_length/l_amount) LOOP

        -- Read in the given chunk of the BLOB.
        DBMS_LOB.READ(l_blob
        ,             l_amount
        ,             l_offset
        ,             l_buffer);

        -- The DBMS_LOB.READ procedure dictates that its output be RAW.
        -- This next procedure converts that RAW data to character data.
        l_text_buffer := UTL_RAW.CAST_TO_VARCHAR2(l_buffer);

        -- For the next iteration through the BLOB, bump up your offset
        -- location (i.e., where you start reading from).
        l_offset := l_offset + l_amount;
    END LOOP;
    RETURN l_text_buffer;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('!ERROR: ' || SUBSTR(SQLERRM,1,247));
END;

END read_gzipped_entity_package;
/

然后运行选择以获取文本

SELECT read_gzipped_entity_package.read_entity('entity_id') FROM DUAL;

希望这会对某人有所帮助。

于 2019-03-14T15:12:51.150 回答
-2

为我工作,

选择 lcase((insert( insert( insert( insert(hex(BLOB_FIELD),9,0,'-'), 14,0,'-'), 19,0,'-'), 24,0,'- '))) 作为来自 TABLE_WITH_BLOB 的 FIELD_ID,其中 ID = '行 id';

于 2018-11-16T06:13:49.953 回答
-6

使用TO_CHAR功能。

select TO_CHAR(BLOB_FIELD) from TABLE_WITH_BLOB where ID = '<row id>'

NCHARNVARCHAR2CLOBNCLOB数据转换为数据库字符集。返回的值始终是VARCHAR2

于 2012-06-17T10:38:25.570 回答