code

Oracle SQL의 BLOB에서 텍스트 콘텐츠를 가져 오는 방법

codestyles 2020. 8. 13. 23:24
반응형

Oracle SQL의 BLOB에서 텍스트 콘텐츠를 가져 오는 방법


Oracle BLOB 내부에 무엇이 있는지 SQL 콘솔에서 확인하려고합니다.

다소 큰 텍스트 본문이 포함되어 있고 텍스트 만보고 싶은데 다음 쿼리는 해당 필드에 BLOB가 있음을 나타냅니다.

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

내가 얻는 결과는 내가 예상했던 것과 다릅니다.

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

그렇다면 BLOB를 텍스트 표현으로 바꾸기 위해 어떤 종류의 마법 주문을 할 수 있습니까?

추신 : 나는 코드에서 사용하지 않고 SQL 콘솔 (Eclipse Data Tools)에서 BLOB의 내용을 보려고합니다.


우선, 바이너리 데이터 용으로 설계된 BLOB 대신 CLOB / NCLOB 열에 텍스트를 저장하고 싶을 수 있습니다 (쿼리는 CLOB와 함께 작동합니다).

다음 쿼리를 사용하면 모든 문자 집합이 호환되는 경우 Blob 내부 텍스트의 처음 32767 자 (최대)를 볼 수 있습니다 (BLOB에 저장된 텍스트의 원래 CS, VARCHAR2에 사용되는 데이터베이스의 CS).

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

아래 SQL을 사용하여 테이블에서 BLOB 필드를 읽을 수 있습니다.

SELECT DBMS_LOB.SUBSTR(BLOB_FIELD_NAME) FROM TABLE_NAME;

SQL Developer는이 기능도 제공합니다.

결과 그리드 셀을 두 번 클릭하고 편집을 클릭합니다.

여기에 이미지 설명 입력

그런 다음 팝업의 오른쪽 상단에 "텍스트로보기"(이미지도 볼 수 있습니다.)

여기에 이미지 설명 입력

그리고 그게 다야!

여기에 이미지 설명 입력


텍스트를 보는 대신 텍스트 내부를 검색하려면 다음과 같이 작동합니다.

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;

잠시이 문제로 어려움을 겪고 PL / SQL 솔루션을 구현했지만 나중에 Toad에서 결과 그리드 셀을 두 번 클릭하면 텍스트로 된 내용이있는 편집기가 표시된다는 사실을 나중에 깨달았습니다. (저는 Toad v11을 사용 중입니다)

여기에 이미지 설명 입력


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;

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


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.


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


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.

참고 URL : https://stackoverflow.com/questions/828650/how-do-i-get-textual-contents-from-blob-in-oracle-sql

반응형