web-dev-qa-db-de.com

Wie erhalte ich Textinhalte von BLOB in Oracle SQL?

Ich versuche, von einer SQL-Konsole aus zu sehen, was sich in einem Oracle-BLOB befindet.

Ich weiß, dass er einen ziemlich großen Text enthält und ich möchte nur den Text sehen, aber die folgende Abfrage zeigt nur an, dass sich in diesem Feld ein BLOB befindet:

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

das Ergebnis, das ich bekomme, ist nicht ganz das, was ich erwartet hatte:

 BLOB_FIELD 
 -----------------------
 [email protected]

Welche Art von Zauberbeschwörungen kann ich also tun, um das BLOB in seine Textdarstellung zu verwandeln?

PS: Ich versuche nur, den Inhalt des BLOB von einer SQL-Konsole (Eclipse Data Tools) aus zu betrachten und nicht im Code zu verwenden.

93
Roland Tepp

Zunächst möchten Sie möglicherweise Text in CLOB/NCLOB-Spalten anstelle von BLOB speichern, das für binäre Daten vorgesehen ist (Ihre Abfrage würde übrigens mit einem CLOB funktionieren).

Die folgende Abfrage zeigt Ihnen die ersten 32767 Zeichen (höchstens) des Textes im Blob an, sofern alle Zeichensätze kompatibel sind (ursprünglicher ZS des im BLOB gespeicherten Textes, ZS der für VARCHAR2 verwendeten Datenbank):

select utl_raw.cast_to_varchar2(dbms_lob.substr(BLOB_FIELD)) from TABLE_WITH_BLOB where ID = '<row id>';
123
Mac

Unter SQL können Sie die BLOB-Felder aus der Tabelle lesen.

SELECT DBMS_LOB.SUBSTR(BLOB_FIELD_NAME) FROM TABLE_NAME;
12
Imran Patel

Wenn Sie im Text suchen möchten, anstatt ihn anzuzeigen, funktioniert dies:

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;
5
Barn

Ich hatte einige Zeit damit zu kämpfen und implementierte die PL/SQL-Lösung. Später wurde mir jedoch klar, dass Sie in Toad einfach auf die Ergebnisrasterzelle doppelklicken können, und es wird ein Editor mit Textinhalten angezeigt. (Ich bin auf Kröte v11)

enter image description here

3
Sonic Soul

SQL Developer bietet auch diese Funktionalität:

Doppelklicken Sie auf die Ergebnisrasterzelle und klicken Sie auf Bearbeiten:

 enter image description here

Dann oben rechts im Popup "Als Text anzeigen" (Sie können sogar Bilder sehen ...)

 enter image description here

Und das ist es!

 enter image description here

3
funkyjelly

Die Antwort von Barn hat für mich mit Modifikationen funktioniert, da meine Kolumne nicht komprimiert ist. Die schnelle und schmutzige Lösung:

select * from my_table
where dbms_lob.instr(my_UNcompressed_blob, utl_raw.cast_to_raw('MY_SEARCH_STRING'))>0;
1
Pecos Bill

Wenn Ihr Text mit dem DEFLATE-Algorithmus im Blob komprimiert wurde und ziemlich groß ist, können Sie ihn mit dieser Funktion lesen

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;
/

Führen Sie dann select aus, um Text abzurufen

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

Hoffe das wird jemandem helfen.

0
Arsen Salamakha

Sie können dies versuchen:

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

Es wäre jedoch auf 4000 Byte begrenzt 

0
Reza Rahimi

Arbeitete für mich, 

select lcase ((insert ( insert ( insert ( insert (hex (BLOB_FIELD)), 9,0, '-'), 14,0, '-'), 19,0, '-'), 24,0, '-'))) als FIELD_ID von TABLE_WITH_BLOB wobei ID = 'Zeilen-ID';

0