Как получить текстовое содержимое из BLOB в Oracle SQL
Вопрос
Я пытаюсь увидеть из консоли SQL, что находится внутри BLOB-объекта Oracle.
Я знаю, что он содержит довольно большой объем текста, и я хочу просто увидеть текст, но следующий запрос только указывает, что в этом поле есть большой двоичный объект:
select BLOB_FIELD from TABLE_WITH_BLOB where ID = '<row id>';
результат, который я получаю, не совсем то, что я ожидал:
BLOB_FIELD ----------------------- oracle.sql.BLOB@1c4ada9
Итак, какие магические заклинания я могу сделать, чтобы превратить BLOB в его текстовое представление?
PS: я просто пытаюсь посмотреть содержимое BLOB из консоли SQL (Eclipse Data Tools), а не использовать его в коде.
Решение
Прежде всего вы можете захотеть хранить текст в столбцах 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>';
Другие советы
Вы можете использовать ниже SQL для чтения полей BLOB из таблицы.
SELECT DBMS_LOB.SUBSTR(BLOB_FIELD_NAME) FROM TABLE_NAME;
Если вы хотите искать внутри текста, а не просматривать его, это работает:
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;
Некоторое время я боролся с этим и реализовал решение PL / SQL, но позже понял, что в Toad вы можете просто дважды щелкнуть ячейку таблицы результатов, и она вызывает редактор с содержимым в тексте. (Я на Жабе v11)
Ответ Барна работал для меня с модификацией, потому что моя колонка не сжата. Быстрое и грязное решение:
select * from my_table
where dbms_lob.instr(my_UNcompressed_blob, utl_raw.cast_to_raw('MY_SEARCH_STRING'))>0;
Вы можете попробовать это:
SELECT TO_CHAR(dbms_lob.substr(BLOB_FIELD, 3900)) FROM TABLE_WITH_BLOB;
Тем не менее, он будет ограничен 4000 байтами
Если ваш текст сжат внутри 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;
Надеюсь, это кому-нибудь поможет.
Работал для меня,
выберите lcase ((вставить ( вставить ( вставить ( вставить (шестигранник (BLOB_FIELD), 9,0, '-'), 14,0, '-'), 19,0, '-'), 24,0, '-'))) как FIELD_ID из TABLE_WITH_BLOB где ID = 'идентификатор строки';
Используйте функцию TO_CHAR
.
select TO_CHAR(BLOB_FIELD) from TABLE_WITH_BLOB where ID = '<row id>'
Преобразует данные NCHAR
, NVARCHAR2
, CLOB
или NCLOB
в набор символов базы данных. Возвращаемое значение всегда VARCHAR2
.