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;
답변
내 열이 압축되지 않았기 때문에 Barn의 대답은 수정으로 나를 위해 일했습니다. 빠르고 더러운 솔루션 :
select * from my_table
where dbms_lob.instr(my_UNcompressed_blob, utl_raw.cast_to_raw('MY_SEARCH_STRING'))>0;
답변
잠시이 문제로 어려움을 겪고 PL / SQL 솔루션을 구현했지만 나중에 Toad에서 결과 그리드 셀을 두 번 클릭하면 텍스트로 된 콘텐츠가있는 편집기가 표시된다는 사실을 나중에 깨달았습니다. (저는 Toad v11을 사용 중입니다)
답변
텍스트가 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;
이것이 누군가를 도울 수 있기를 바랍니다.