Как получить текстовое содержимое из BLOB в Oracle SQL - PullRequest
96 голосов
/ 06 мая 2009

Я пытаюсь увидеть из консоли SQL, что находится внутри BLOB-объекта Oracle.

Я знаю, что он содержит довольно большой объем текста, и я хочу просто увидеть текст, но следующий запрос только указывает, что в этом поле есть BLOB:

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

результат, который я получаю, не совсем то, что я ожидал:

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

Итак, какие магические заклинания я могу сделать, чтобы превратить BLOB в его текстовое представление?

PS: я просто пытаюсь посмотреть содержимое BLOB с консоли SQL (Eclipse Data Tools), а не использовать его в коде.

Ответы [ 10 ]

128 голосов
/ 06 мая 2009

Прежде всего вы можете захотеть хранить текст в столбцах CLOB / NCLOB вместо BLOB, который предназначен для двоичных данных (кстати, ваш запрос будет работать с CLOB).

Следующий запрос позволит вам увидеть первые 32767 символов (не более) текста внутри большого двоичного объекта, при условии, что все наборы символов совместимы (исходный CS текста, сохраненного в BLOB, CS базы данных, используемой для VARCHAR2 ):

select utl_raw.cast_to_varchar2(dbms_lob.substr(BLOB_FIELD)) from TABLE_WITH_BLOB where ID = '<row id>';
13 голосов
/ 23 декабря 2014

Вы можете использовать ниже SQL для чтения полей BLOB из таблицы.

SELECT DBMS_LOB.SUBSTR(BLOB_FIELD_NAME) FROM TABLE_NAME;
5 голосов
/ 07 декабря 2018

SQL Developer также предоставляет эту функциональность:

Дважды щелкните ячейку сетки результатов и нажмите «Изменить»:

enter image description here

Затем в правой верхней части всплывающего окна «Просмотреть как текст» (Вы даже можете видеть изображения ..)

enter image description here

И это все!

enter image description here

5 голосов
/ 18 февраля 2014

Если вы хотите искать внутри текста, а не просматривать его, это работает:

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;
3 голосов
/ 13 мая 2014

Я некоторое время боролся с этим и реализовал решение PL / SQL, но позже понял, что в Toad вы можете просто дважды щелкнуть по ячейке таблицы результатов, и она вызывает редактор с содержимым в тексте. (Я на Жабе v11)

enter image description here

1 голос
/ 11 апреля 2014

Ответ Барна работал для меня с модификацией, потому что моя колонка не сжата. Быстрое и грязное решение:

select * from my_table
where dbms_lob.instr(my_UNcompressed_blob, utl_raw.cast_to_raw('MY_SEARCH_STRING'))>0;
0 голосов
/ 14 марта 2019

Если ваш текст сжат внутри BLOB-объекта с использованием алгоритма DEFLATE и он достаточно велик, вы можете использовать эту функцию для его чтения

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, чтобы получить текст

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

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 16 ноября 2018

работал для меня,

выберите lcase ((вставить ( вставить ( вставить ( вставить (шестигранник (BLOB_FIELD), 9,0, '-'), 14,0, '-'), 19,0, '-'), 24,0, '-'))) как FIELD_ID из TABLE_WITH_BLOB где ID = 'идентификатор строки';

0 голосов
/ 13 июля 2018

Вы можете попробовать это:

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

Однако, он будет ограничен 4000 байт

0 голосов
/ 17 июня 2012

Используйте функцию TO_CHAR.

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

Преобразует данные NCHAR, NVARCHAR2, CLOB или NCLOB в набор символов базы данных. Возвращаемое значение всегда VARCHAR2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...