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


112

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의 내용을 보려고합니다.

답변:


141

우선, 바이너리 데이터 용으로 설계된 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>';

3
불행히도 저는 데이터베이스 스키마를 제어하지 않습니다. 블롭을 들여다 보면됩니다 ... 어쨌든 감사합니다.
Roland Tepp

고마워요 Mac, 잘 작동합니다 ---하지만 "dbms_lob.substr"의 목적은 무엇입니까? --- "select utl_raw.cast_to_varchar2 (BLOB_FIELD) ..."만 사용하면 동일한 결과가 나오는 것 같습니다 ...?
Rop aug

4
cast_to_varchar2는 길이가 32767 바이트로 제한되는 입력 ( docs.oracle.com/cd/E11882_01/appdev.112/e25788/… ) 에서 RAW를 가져옵니다 ( 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 : 숫자 또는 값 오류 : 원시 변수 길이가 너무 깁니다"라는 메시지가 나타납니다. BLOB_FIELD 뒤에 "2000,1"을 입력하여 최대 2000자를 얻을 수 있지만 그 이상은 없습니다.
Mark

2
값이 4000보다 길면 SQL의 문자열에 대한 최대 값이므로 오류가 발생합니다. substr (BLOB_FIELD, 4000, 1)을 추가해야합니다. 더 긴 현장 지원이 필요한 경우 PL / SQL을 사용하십시오 (내 생각에는 최대 32000
Sonic Soul

14

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

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에서 결과 그리드 셀을 두 번 클릭하면 텍스트로 된 콘텐츠가있는 편집기가 표시된다는 사실을 나중에 깨달았습니다. (저는 Toad v11을 사용 중입니다)

여기에 이미지 설명 입력


1

텍스트가 DEFLATE 알고리즘을 사용하여 Blob 내부에서 압축되고 크기가 매우 큰 경우이 함수를 사용하여 읽을 수 있습니다.

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를 실행하여 텍스트를 가져옵니다.

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

이것이 누군가를 도울 수 있기를 바랍니다.


1

이 SQL을 사용하여 BLOB의 처음 2000자를 가져옵니다.

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

참고 : 이는 Oracle이 길이가 2000을 초과하는 BLOB의 변환을 처리 할 수 ​​없기 때문입니다.


0

이것을 시도 할 수 있습니다.

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

그러나 4000 바이트로 제한됩니다.


-2

나를 위해 일했습니다.

select lcase ((insert (insert (insert (insert (hex (BLOB_FIELD), 9,0, '-'), 14,0, '-'), 19,0, '-'), 24,0, '- '))) TABLE_WITH_BLOB의 FIELD_ID로 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입니다.


SELECT DBMS_LOB.SUBSTR (BLOB_FIELD) FROM TABLE_WITH_BLOB;
Sambhav 2015 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.