Bagaimana cara mendapatkan konten tekstual dari BLOB di Oracle SQL

112

Saya mencoba untuk melihat dari konsol SQL apa yang ada di dalam BLOB Oracle.

Saya tahu ini berisi teks yang agak besar dan saya hanya ingin melihat teksnya, tetapi kueri berikut hanya menunjukkan bahwa ada BLOB di bidang itu:

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

hasil yang saya dapatkan tidak seperti yang saya harapkan:

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

Jadi mantra sihir apa yang dapat saya lakukan untuk mengubah BLOB menjadi representasi tekstualnya?

NB: Saya hanya mencoba untuk melihat konten BLOB dari konsol SQL (Alat Data Eclipse), bukan menggunakannya dalam kode.

Roland Tepp
sumber

Jawaban:

141

Pertama-tama, Anda mungkin ingin menyimpan teks di kolom CLOB / NCLOB daripada di BLOB, yang dirancang untuk data biner (kueri Anda akan bekerja dengan CLOB).

Kueri berikut akan membiarkan Anda melihat 32.767 karakter pertama (paling banyak) dari teks di dalam blob, asalkan semua set karakter kompatibel (CS asli dari teks yang disimpan di BLOB, CS dari database yang digunakan untuk VARCHAR2):

select utl_raw.cast_to_varchar2(dbms_lob.substr(BLOB_FIELD)) from TABLE_WITH_BLOB where ID = '<row id>';
Mac
sumber
3
Sayangnya, saya tidak mengontrol skema database - saya hanya perlu mengintip ke dalam blob ... Tapi terima kasih.
Roland Tepp
Terima kasih Mac, itu berfungsi dengan baik --- Tapi apa tujuan dari "dbms_lob.substr" itu? --- Hanya menggunakan "pilih utl_raw.cast_to_varchar2 (BLOB_FIELD) ..." sepertinya memberi saya hasil yang sama ...?
Rop
4
cast_to_varchar2 mengambil masukan RAW ( docs.oracle.com/cd/E11882_01/appdev.112/e25788/… ), yang dibatasi hingga 32.767 byte ( docs.oracle.com/cd/E11882_01/appdev.112/e10472 /… ). BLOB tidak memiliki batasan ukuran, jadi substr memotongnya ke ukuran yang benar ( docs.oracle.com/cd/E11882_01/appdev.112/e25788/… ) jika perlu.
Mac
34
Tidak bekerja untuk saya - Saya mendapatkan "ORA-06502: PL / SQL: kesalahan angka atau nilai: panjang variabel mentah terlalu panjang". Saya dapat meletakkan "2000,1" setelah BLOB_FIELD untuk mendapatkan hingga 2000 karakter, tetapi tidak lebih dari itu.
Tandai
2
jika nilainya lebih lama dari 4000 itu akan menimbulkan kesalahan karena itu nilai maksimal untuk string di sql. Anda perlu menambahkan substr (BLOB_FIELD, 4000, 1). Jika Anda membutuhkan dukungan lapangan yang lebih lama, gunakan PL / SQL (hingga 32000 saya percaya)
Sonic Soul
14

Anda dapat menggunakan SQL di bawah ini untuk membaca BLOB Fields dari tabel.

SELECT DBMS_LOB.SUBSTR(BLOB_FIELD_NAME) FROM TABLE_NAME;
Imran Patel
sumber
Saya memiliki kolom BLOB dan di mana data XML dikompresi dan disimpan dalam tabel, ketika saya membaca data, itu hanya menunjukkan beberapa angka dan bukan teks xml yang sebenarnya, apa yang harus saya lakukan untuk membaca data teks XML dari tabel.
BHUVANESH MOHANKUMAR
14

Pengembang SQL menyediakan fungsionalitas ini juga:

Klik dua kali sel kisi hasil, dan klik edit:

masukkan deskripsi gambar di sini

Kemudian di bagian kanan atas pop-up, "View As Text" (Anda bahkan dapat melihat gambar ..)

masukkan deskripsi gambar di sini

Dan itu dia!

masukkan deskripsi gambar di sini

nullPointer
sumber
Itu tip yang bagus - terima kasih!
Ed Graham
7

Jika Anda ingin mencari di dalam teks, daripada melihatnya, ini berfungsi:

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;
Lumbung
sumber
apa my_id disini?
anjanb
Ini tidak berfungsi untuk saya, saya memiliki kolom BLOB dan di mana data XML dikompresi dan disimpan dalam tabel, ketika saya membaca data, itu hanya menunjukkan beberapa angka dan bukan teks xml yang sebenarnya, apa yang harus saya lakukan untuk membaca teks XML data dari tabel.
BHUVANESH MOHANKUMAR
3

Jawaban Barn berfungsi untuk saya dengan modifikasi karena kolom saya tidak dikompresi. Solusi cepat dan kotor:

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

Saya berjuang dengan ini untuk sementara waktu dan menerapkan solusi PL / SQL, tetapi kemudian menyadari bahwa di Toad Anda cukup mengklik dua kali pada sel kisi hasil, dan itu menampilkan editor dengan konten dalam teks. (Saya menggunakan Toad v11)

masukkan deskripsi gambar di sini

Sonic Soul
sumber
1

Jika teks Anda dikompresi di dalam blob menggunakan algoritme DEFLATE dan ukurannya cukup besar, Anda dapat menggunakan fungsi ini untuk membacanya

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

Kemudian jalankan pilih untuk mendapatkan teks

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

Semoga ini bisa membantu seseorang.

Arsen Salamakha
sumber
1

Gunakan SQL ini untuk mendapatkan 2000 karakter pertama BLOB.

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

Catatan: Ini karena, Oracle tidak akan dapat menangani konversi BLOB yang lebih dari 2000 panjang.

Swapnil Ingle
sumber
0

Anda dapat mencoba ini:

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

Namun, itu akan dibatasi hingga 4000 byte

Reza Rahimi
sumber
-2

Bekerja untuk saya,

pilih lcase ((sisipkan (sisipkan (sisipkan (sisipkan (hex (BLOB_FIELD), 9,0, '-'), 14,0, '-'), 19,0, '-'), 24,0, '- '))) sebagai FIELD_ID dari TABLE_WITH_BLOB di mana ID =' baris id ';

Narendra Kalekar
sumber
Jika ini berhasil untuk Anda, maka Anda tidak menggunakan Oracle, yang merupakan OP dan itulah mengapa jawabannya harus berupa sintaks Oracle yang valid.
APC
-4

Gunakan TO_CHARfungsi.

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

Bertobat NCHAR, NVARCHAR2, CLOB, atau NCLOBdata ke set karakter database. Nilai yang dikembalikan selalu VARCHAR2.

Alex
sumber
PILIH DBMS_LOB.SUBSTR (BLOB_FIELD) DARI TABLE_WITH_BLOB;
Sambhav