ฉันจะรับเนื้อหาที่เป็นข้อความจาก BLOB ใน Oracle SQL ได้อย่างไร


112

ฉันพยายามดูจากคอนโซล SQL ว่ามีอะไรอยู่ใน Oracle BLOB

ฉันรู้ว่ามันมีเนื้อหาค่อนข้างใหญ่และฉันต้องการแค่ดูข้อความ แต่แบบสอบถามต่อไปนี้ระบุว่ามี BLOB อยู่ในฟิลด์นั้นเท่านั้น:

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

ผลลัพธ์ที่ฉันได้รับไม่ใช่สิ่งที่ฉันคาดหวัง:

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

ดังนั้นฉันสามารถใช้เวทมนตร์แบบใดเพื่อเปลี่ยน BLOB ให้เป็นการแสดงข้อความได้

PS: ฉันแค่พยายามดูเนื้อหาของ BLOB จากคอนโซล SQL (Eclipse Data Tools) ไม่ใช่ใช้ในโค้ด

คำตอบ:


141

ก่อนอื่นคุณอาจต้องการจัดเก็บข้อความในคอลัมน์ CLOB / NCLOB แทน BLOB ซึ่งออกแบบมาสำหรับข้อมูลไบนารี (ข้อความค้นหาของคุณจะทำงานร่วมกับ CLOB ได้)

แบบสอบถามต่อไปนี้จะช่วยให้คุณเห็นอักขระ 32767 ตัวแรก (สูงสุด) ของข้อความภายในหยดหากชุดอักขระทั้งหมดเข้ากันได้ (CS ดั้งเดิมของข้อความที่จัดเก็บใน BLOB, CS ของฐานข้อมูลที่ใช้สำหรับ VARCHAR2):

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

3
น่าเสียดายที่ฉันไม่ได้ควบคุมสคีมาฐานข้อมูล - ฉันแค่ต้องมองเข้าไปในหยด ... แต่ยังไงก็ขอบคุณ
Roland Tepp

ขอบคุณ Mac ที่ใช้งานได้ดี --- แต่ "dbms_lob.substr" นั้นมีจุดประสงค์อะไร --- ใช้เฉพาะ "select utl_raw.cast_to_varchar2 (BLOB_FIELD) ... " ดูเหมือนจะให้ผลลัพธ์เหมือนกัน ... ?
Rop

4
cast_to_varchar2 รับ RAW ในอินพุต ( docs.oracle.com/cd/E11882_01/appdev.112/e25788/… ) ซึ่งจำกัดความยาวไว้ที่ 32767 ไบต์ ( docs.oracle.com/cd/E11882_01/appdev.112/e10472 / … ). BLOB ไม่มีข้อ จำกัด ด้านขนาดดังนั้น substr จึงตัดทอนให้มีขนาดที่ถูกต้อง ( docs.oracle.com/cd/E11882_01/appdev.112/e25788/… ) หากจำเป็น
Mac

34
ไม่ได้ผลสำหรับฉัน - ฉันได้รับ "ORA-06502: PL / SQL: ข้อผิดพลาดเกี่ยวกับตัวเลขหรือค่า: ความยาวตัวแปรดิบยาวเกินไป" ฉันสามารถใส่ "2000,1" หลัง BLOB_FIELD เพื่อให้ได้สูงสุด 2,000 ตัวอักษร แต่ไม่มีอะไรนอกเหนือไปจากนั้น
มาร์ค

2
หากค่ายาวกว่า 4000 จะทำให้เกิดข้อผิดพลาดเนื่องจากเป็นค่าสูงสุดสำหรับสตริงใน sql คุณต้องเพิ่ม substr (BLOB_FIELD, 4000, 1) ถ้าคุณต้องการการสนับสนุนภาคสนามอีกต่อไปให้ใช้ PL / SQL (ถึง 32000 ฉันเชื่อว่า)
Sonic Soul

14

คุณสามารถใช้ SQL ด้านล่างเพื่ออ่าน BLOB Fields จากตาราง

SELECT DBMS_LOB.SUBSTR(BLOB_FIELD_NAME) FROM TABLE_NAME;

ฉันมีคอลัมน์ BLOB และที่ที่ข้อมูล XML ถูกบีบอัดและจัดเก็บในตารางเมื่อฉันอ่านข้อมูลจะแสดงตัวเลขเพียงบางส่วนไม่ใช่ข้อความ xml จริงฉันควรทำอย่างไรเพื่ออ่านข้อมูลข้อความ XML จากตาราง
BHUVANESH MOHANKUMAR

14

SQL Developer มีฟังก์ชันนี้ด้วย:

ดับเบิลคลิกเซลล์ตารางผลลัพธ์แล้วคลิกแก้ไข:

ใส่คำอธิบายภาพที่นี่

จากนั้นที่ส่วนบนขวาของป๊อปอัป "ดูเป็นข้อความ" (คุณยังสามารถดูภาพ .. )

ใส่คำอธิบายภาพที่นี่

แค่นี้แหละ!

ใส่คำอธิบายภาพที่นี่


นั่นเป็นเคล็ดลับที่ดี - ขอบคุณ!
Ed Graham

7

หากคุณต้องการค้นหาภายในข้อความแทนที่จะดูสิ่งนี้ใช้ได้:

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;

my_id ที่นี่คืออะไร
anjanb

สิ่งนี้ใช้ไม่ได้สำหรับฉันฉันมีคอลัมน์ BLOB และที่ที่ข้อมูล XML ถูกบีบอัดและเก็บไว้ในตารางเมื่อฉันอ่านข้อมูลจะแสดงตัวเลขบางส่วนเท่านั้นไม่ใช่ข้อความ xml จริงฉันควรทำอย่างไรเพื่ออ่านข้อความ XML ข้อมูลจากตาราง
BHUVANESH MOHANKUMAR

3

คำตอบของ Barn ใช้ได้ผลกับฉันด้วยการปรับเปลี่ยนเนื่องจากคอลัมน์ของฉันไม่ได้ถูกบีบอัด วิธีแก้ปัญหาที่รวดเร็วและสกปรก:

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

3

ฉันต่อสู้กับสิ่งนี้มาระยะหนึ่งแล้วและนำโซลูชัน PL / SQL มาใช้ แต่ภายหลังตระหนักว่าใน Toad คุณสามารถดับเบิลคลิกที่เซลล์ตารางผลลัพธ์และจะแสดงตัวแก้ไขที่มีเนื้อหาเป็นข้อความ (ฉันอยู่บนคางคก v11)

ใส่คำอธิบายภาพที่นี่


1

ในกรณีที่ข้อความของคุณถูกบีบอัดภายในหยดโดยใช้อัลกอริทึม DEFLATE และมีขนาดค่อนข้างใหญ่คุณสามารถใช้ฟังก์ชันนี้เพื่ออ่านได้

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

จากนั้นเรียกใช้เลือกเพื่อรับข้อความ

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

หวังว่านี่จะช่วยใครบางคนได้


1

ใช้ SQL นี้เพื่อรับ 2,000 ตัวอักษรแรกของ BLOB

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

หมายเหตุ:เนื่องจาก Oracle จะไม่สามารถจัดการกับการแปลง BLOB ที่มีความยาวเกิน 2000 ได้



-2

ทำงานให้ฉัน

เลือก lcase ((แทรก (แทรก (แทรก (แทรก (ฐานสิบหก (BLOB_FIELD), 9,0, '-'), 14,0, '-'), 19,0, '-'), 24,0, '- '))) เป็น FIELD_ID จาก TABLE_WITH_BLOB โดยที่ ID =' row id ';


หากสิ่งนี้ใช้ได้ผลสำหรับคุณแสดงว่าคุณไม่ได้ใช้ Oracle ซึ่ง OP คือสาเหตุที่คำตอบต้องเป็นไวยากรณ์ของ Oracle ที่ถูกต้อง
APC

-4

ใช้TO_CHARฟังก์ชัน

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

แปลงNCHAR, NVARCHAR2, CLOBหรือNCLOBข้อมูลไปยังชุดอักขระฐานข้อมูล VARCHAR2ค่าส่งกลับอยู่เสมอ


เลือก DBMS_LOB.SUBSTR (BLOB_FIELD) จาก TABLE_WITH_BLOB;
Sambhav
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.