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.

Foi útil?

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;

O SQL Developer também fornece essa funcionalidade:

Clique duas vezes na célula da grade de resultados e clique em Editar:

enter image description here

Então, na parte superior direita do pop-up, "Visualizar como texto" (você pode até ver imagens ..)

enter image description here

E é isso!

enter image description here

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)

enter image description here

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top