How do I get textual contents from BLOB in Oracle SQL
Asked Answered
M

12

145

I am trying to see from an SQL console what is inside an Oracle BLOB.

I know it contains a somewhat large body of text and I want to just see the text, but the following query only indicates that there is a BLOB in that field:

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

the result I'm getting is not quite what I expected:

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

So what kind of magic incantations can I do to turn the BLOB into it's textual representation?

PS: I am just trying to look at the content of the BLOB from an SQL console (Eclipse Data Tools), not use it in code.

Meliorate answered 6/5, 2009 at 8:41 Comment(0)
B
174

First of all, you may want to store text in CLOB/NCLOB columns instead of BLOB, which is designed for binary data (your query would work with a CLOB, by the way).

The following query will let you see the first 32767 characters (at most) of the text inside the blob, provided all the character sets are compatible (original CS of the text stored in the BLOB, CS of the database used for VARCHAR2) :

select utl_raw.cast_to_varchar2(dbms_lob.substr(BLOB_FIELD)) from TABLE_WITH_BLOB where ID = '<row id>';
Bettis answered 6/5, 2009 at 9:36 Comment(7)
Unfortunately, I do not control the database schema - I just need to peek into the blob... But thanks anyway.Meliorate
Thanks Mac, that works fine --- But what is the purpose of that "dbms_lob.substr"? --- Only using "select utl_raw.cast_to_varchar2(BLOB_FIELD) ..." seems to give me the same result...?Sciential
cast_to_varchar2 takes a RAW in input (docs.oracle.com/cd/E11882_01/appdev.112/e25788/…), which is limited to 32767 bytes in length (docs.oracle.com/cd/E11882_01/appdev.112/e10472/…). A BLOB has no limitation in size, so substr truncates it to a correct size (docs.oracle.com/cd/E11882_01/appdev.112/e25788/…) if necessary.Bettis
Doesn't work for me - I get "ORA-06502: PL/SQL: numeric or value error: raw variable length too long". I can put "2000,1" after BLOB_FIELD to get up to 2000 chars, but nothing beyond that.Accident
if the value is longer than 4000 it will throw errors since that's max value for strings in sql. you need to add substr(BLOB_FIELD, 4000, 1). If yo u need longer field support use PL/SQL (up to 32000 I believe)Encyclopedist
Can LZ_UNCOMPRESS be used with any of these BLOB fields via SQL - or does that strictly require use of the procedural language SQL of Oracle?Aiden
it gives me "ORA-00904: "URL_RAW"."CAST_TO_VARCHAR2": invalid identifier" errorIntercolumniation
E
37

SQL Developer provides this functionality too :

Double click the results grid cell, and click edit :

enter image description here

Then on top-right part of the pop up , "View As Text" (You can even see images..)

enter image description here

And that's it!

enter image description here

Entomo answered 7/12, 2018 at 15:12 Comment(1)
@Entomo you are so awesome man! Thanks for the tip.Embryogeny
H
19

You can use below SQL to read the BLOB Fields from table.

SELECT DBMS_LOB.SUBSTR(BLOB_FIELD_NAME) FROM TABLE_NAME;
Headstone answered 23/12, 2014 at 10:57 Comment(2)
I have BLOB column and where the XML data is compressed and stored in the table, when I read the data, it shows only some numbers and not actual xml text, what should I do to read the XML text data from table.Elul
This is not working,raw variable length too long errorNatelson
S
14

Use this SQL to get the first 2000 chars of the BLOB.

SELECT utl_raw.cast_to_varchar2(dbms_lob.substr(<YOUR_BLOB_FIELD>,2000,1)) FROM <YOUR_TABLE>;

Note: This is because, Oracle will not be able to handle the conversion of BLOB that is more than length 2000.

Sweptback answered 15/1, 2020 at 14:25 Comment(0)
A
10

I can get this to work using TO_CLOB (docs):

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

This works for me in Oracle 19c, with a BLOB field which larger the the VARCHAR limit. I get readable text (from a JSON-holding BLOB)

Assassinate answered 20/7, 2021 at 16:51 Comment(0)
B
8

If you want to search inside the text, rather than view it, this works:

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;
Brom answered 18/2, 2014 at 17:13 Comment(2)
what is my_id here ?Countrybred
This is not working for me, I have BLOB column and where the XML data is compressed and stored in the table, when I read the data, it shows only some numbers and not actual xml text, what should I do to read the XML text data from table.Elul
T
4

Barn's answer worked for me with modification because my column is not compressed. The quick and dirty solution:

select * from my_table
where dbms_lob.instr(my_UNcompressed_blob, utl_raw.cast_to_raw('MY_SEARCH_STRING'))>0;
Tritanopia answered 11/4, 2014 at 17:13 Comment(0)
E
3

I struggled with this for a while and implemented the PL/SQL solution, but later realized that in Toad you can simply double click on the results grid cell, and it brings up an editor with contents in text. (i'm on Toad v11)

enter image description here

Encyclopedist answered 13/5, 2014 at 13:6 Comment(0)
S
3

In case your text is compressed inside the blob using DEFLATE algorithm and it's quite large, you can use this function to read it

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

Then run select to get text

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

Hope this will help someone.

Seamanship answered 14/3, 2019 at 15:12 Comment(0)
G
1

You can try this:

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

However, It would be limited to 4000 byte

Grissel answered 13/7, 2018 at 19:49 Comment(0)
K
-2

Worked for me,

select lcase((insert( insert( insert( insert(hex(BLOB_FIELD),9,0,'-'), 14,0,'-'), 19,0,'-'), 24,0,'-'))) as FIELD_ID from TABLE_WITH_BLOB where ID = 'row id';

Kristelkristen answered 16/11, 2018 at 6:13 Comment(1)
If this worked for you then you are not using Oracle, which the OP is and that's why the answers need to be valid Oracle syntax.Theodor
E
-5

Use TO_CHAR function.

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

Converts NCHAR, NVARCHAR2, CLOB, or NCLOB data to the database character set. The value returned is always VARCHAR2.

Enfeeble answered 17/6, 2012 at 10:38 Comment(1)
SELECT DBMS_LOB.SUBSTR(BLOB_FIELD) FROM TABLE_WITH_BLOB;Wil

© 2022 - 2024 — McMap. All rights reserved.