質問

SQLコンソールからOracle BLOBの内部を確認しようとしています。

やや大きなテキストが含まれていることは知っているので、テキストだけを表示したいのですが、次のクエリはそのフィールドにBLOBがあることを示しているだけです。

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

私が得ている結果は、私が期待したものとはまったく異なります:

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

では、BLOBをテキスト表現にするには、どのような魔法の呪文を使用できますか?

PS:コードで使用するのではなく、SQLコンソール(Eclipse Data Tools)からBLOBのコンテンツを見ようとしています。

役に立ちましたか?

解決

まず、バイナリデータ用に設計されたBLOBではなく、CLOB / NCLOB列にテキストを格納することをお勧めします(ちなみに、クエリはCLOBで機能します)。

次のクエリでは、すべての文字セットに互換性がある場合(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;

テキストを表示するのではなく、テキスト内を検索する場合、これは機能します:

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;

SQL Developerはこの機能も提供します:

結果グリッドセルをダブルクリックし、[編集]をクリックします。

ここに画像の説明を入力

ポップアップの右上にある「テキストとして表示」 (画像も見ることができます。)

ここに画像の説明を入力

これで完了です!

ここに画像の説明を入力

しばらくの間これに苦労し、PL / SQLソリューションを実装しましたが、後でToadでは結果グリッドセルをダブルクリックするだけで、テキストの内容を含むエディターが表示されることに気付きました。 (Toad v11を使用しています)

ここに画像の説明を入力

私のコラムは圧縮されていないので、Barnの答えは修正してもうまくいきました。迅速で汚い解決策:

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

これを試すことができます:

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

ただし、4000バイトに制限されます

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;

これが誰かの助けになることを願っています。

私のために働いた、

  

select lcase((insert(           インサート(             インサート(               insert(hex(BLOB_FIELD)、9,0、 '-')、               14,0、 '-')、             19,0、 '-')、           FIELD_IDとして24,0、 '-'))))   TABLE_WITH_BLOBから   ここで、ID = 'row id';

TO_CHAR 関数を使用します。

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

NCHAR NVARCHAR2 CLOB 、または NCLOB データをデータベースの文字セットに変換します。返される値は常に VARCHAR2 です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top