Como faço para obter conteúdo textual do BLOB no Oracle SQL
Pergunta
Estou tentando ver de um console SQL o que está dentro de uma blob Oracle.
Eu sei que ele contém um corpo um pouco grande de texto e quero apenas ver o texto, mas a consulta a seguir indica apenas que há uma bolha nesse campo:
select BLOB_FIELD from TABLE_WITH_BLOB where ID = '<row id>';
O resultado que estou obtendo não é exatamente o que esperava:
BLOB_FIELD ----------------------- oracle.sql.BLOB@1c4ada9
Então, que tipo de encantamentos mágicos posso fazer para transformar a bolha em sua representação textual?
PS: Estou apenas tentando analisar o conteúdo do blob de um console SQL (Eclipse Data Tools), não o use no código.
Solução
Primeiro de tudo, você pode armazenar texto em colunas CLOB/NCLOB em vez de BLOB, que é projetado para dados binários (sua consulta funcionaria com um CLOB, a propósito).
A consulta a seguir permitirá que você veja os primeiros 32767 caracteres (no máximo) do texto dentro da bolha, desde que todos os conjuntos de caracteres sejam compatíveis (CS original do texto armazenado no blob, CS do banco de dados usado para varchar2):
select utl_raw.cast_to_varchar2(dbms_lob.substr(BLOB_FIELD)) from TABLE_WITH_BLOB where ID = '<row id>';
Outras dicas
Você pode usar abaixo do SQL para ler os campos do blob da tabela.
SELECT DBMS_LOB.SUBSTR(BLOB_FIELD_NAME) FROM TABLE_NAME;
Se você deseja pesquisar dentro do texto, em vez de vê -lo, isso funciona:
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;
Eu lutei com isso por um tempo e implementei a solução PL/SQL, mas depois percebi que no sapo você pode simplesmente clicar duas vezes na célula da grade de resultados e traz um editor com conteúdo no texto. (Estou no Toad v11)
A resposta de Barn funcionou para mim com modificação porque minha coluna não está compactada. A solução rápida e suja:
select * from my_table
where dbms_lob.instr(my_UNcompressed_blob, utl_raw.cast_to_raw('MY_SEARCH_STRING'))>0;
Você pode tentar isso:
SELECT TO_CHAR(dbms_lob.substr(BLOB_FIELD, 3900)) FROM TABLE_WITH_BLOB;
No entanto, seria limitado a 4000 byte
Caso seu texto seja compactado dentro da bolha usando o algoritmo esfarrapado e é bastante grande, você pode usar essa função para lê -la
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;
/
Em seguida, execute selecione para obter texto
SELECT read_gzipped_entity_package.read_entity('entity_id') FROM DUAL;
Espero que isso ajude alguém.
Trabalhou para mim,
Selecione LCase ((inserir (inserir (inserir (inserir (hex (blob_field), 9,0, '-'), 14,0, '-'), 19,0, '-'), 24,0, '-- '))) como field_id de tabela_with_blob onde id =' linha id ';
Usar TO_CHAR
função.
select TO_CHAR(BLOB_FIELD) from TABLE_WITH_BLOB where ID = '<row id>'
Convertidos NCHAR
, NVARCHAR2
, CLOB
, ou NCLOB
dados para o conjunto de caracteres do banco de dados. O valor retornado é sempre VARCHAR2
.