Як отримати текстовий вміст від 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
На жаль, я не контролюю схему бази даних - мені просто потрібно зазирнути в кльош ... Але все одно дякую.
Роланд Тепп

Спасибі 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/… ), якщо це необхідно.
Мак

34
Не працює для мене - я отримую "ORA-06502: PL / SQL: числова помилка або помилка: необмежена довжина змінної занадто довга". Я можу поставити "2000,1" після BLOB_FIELD, щоб отримати до 2000 символів, але нічого більше за це.
Марк

2
якщо значення довше 4000, воно призведе до помилок, оскільки це максимальне значення для рядків у sql. вам потрібно додати субстр. (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 з таблиці.
БХУВАНЕШ МОХАНКУМАР

14

SQL Developer також забезпечує цю функціональність:

Двічі клацніть на клітинці сітки результатів та натисніть Редагувати:

введіть тут опис зображення

Потім у правій верхній частині спливаючого вікна "Переглянути як текст" (Ви навіть можете бачити зображення ..)

введіть тут опис зображення

І це все!

введіть тут опис зображення


Це чудова порада - дякую!
Ед Грем

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;

що тут мій_ід?
anjanb

Це не працює для мене, у мене стовпчик BLOB, і де дані XML стискаються та зберігаються в таблиці, коли я читаю дані, вони показують лише деякі цифри, а не фактичний XML-текст, що мені робити, щоб прочитати XML-текст дані з табл.
БХУВАНЕШ МОХАНКУМАР

3

Відповідь Барна працювала на мене з модифікацією, оскільки мій стовпчик не стискається. Швидке і брудне рішення:

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 і він досить великий, ви можете скористатися цією функцією, щоб прочитати його

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, щоб отримати перші 2000 символів BLOB.

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

Примітка. Це тому, що Oracle не зможе впоратися з конвертацією BLOB, що перевищує довжину 2000.


0

Ви можете спробувати це:

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

Однак це буде обмежено 4000 байт


-2

Працювали для мене,

виберіть lcase ((вставка (вставка (вставка (вставка (вставка (шестигранний (BLOB_FIELD), 9,0, '-'), 14,0, '-'), 19,0, '-'), 24,0, '- '))) як FIELD_ID від TABLE_WITH_BLOB, де ID =' ідентифікатор рядка ';


Якщо це спрацювало для вас, тоді ви не використовуєте Oracle, що є операційною програмою, і тому відповіді повинні бути дійсними синтаксисом 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;
Самбхав
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.