База данных Oracle: как читать BLOB?

Я работаю с базой данных Oracle, и я хотел бы прочитать содержимое BLOB. Как мне это сделать?

Когда я делаю простой оператор select, он просто возвращает "(BLOB)" (без кавычек). Как читать фактическое содержимое?

Ответ 1

SQL Developer может отображать blob как изображение (по крайней мере, он работает для jpegs). В представлении "Данные" дважды щелкните поле BLOB, чтобы получить значок "карандаш". Нажмите на карандаш, чтобы получить диалог, который позволит вам выбрать флажок "Посмотреть как изображение".

Ответ 2

Вы можете сбросить значение в шестнадцатеричном формате с помощью UTL_RAW.CAST_TO_RAW(UTL_RAW.CAST_TO_VARCHAR2()).

SELECT b FROM foo;
-- (BLOB)

SELECT UTL_RAW.CAST_TO_RAW(UTL_RAW.CAST_TO_VARCHAR2(b))
FROM foo;
-- 1F8B080087CDC1520003F348CDC9C9D75128CF2FCA49D1E30200D7BBCDFC0E000000

Это удобно, потому что это тот же формат, который используется для вставки в столбцы BLOB:

CREATE GLOBAL TEMPORARY TABLE foo (
    b BLOB);
INSERT INTO foo VALUES ('1f8b080087cdc1520003f348cdc9c9d75128cf2fca49d1e30200d7bbcdfc0e000000');

DESC foo;
-- Name Null Type 
-- ---- ---- ---- 
-- B        BLOB 

Однако, в определенной точке (2000 байт?) соответствующая шестнадцатеричная строка превышает максимальную длину строки Oracles. Если вам нужно обработать этот случай, вы должны объединить Как получить текстовое содержимое из BLOB в Oracle SQL с помощью документация для DMBS_LOB.SUBSTR для более сложного подхода, который позволит вам увидеть подстроки BLOB.

Ответ 3

Если содержимое не слишком велико, вы также можете использовать

SELECT CAST ( <blobfield> AS RAW( <maxFieldLength> ) ) FROM <table>;

или

SELECT DUMP ( CAST ( <blobfield> AS RAW( <maxFieldLength> ) ) ) FROM <table>;

Это покажет вам значения HEX.

Ответ 4

Если вы используете собственный поставщик данных Oracle, а не драйвер Microsoft, вы можете получить все типы полей

Dim cn As New Oracle.DataAccess.Client.OracleConnection
Dim cm As New Oracle.DataAccess.Client.OracleCommand
Dim dr As Oracle.DataAccess.Client.OracleDataReader

Строка подключения не требует значения Provider, поэтому вы должны использовать что-то вроде:

"Data Source=myOracle;UserID=Me;Password=secret"

Откройте соединение:

cn.ConnectionString = "Data Source=myOracle;UserID=Me;Password=secret"
cn.Open()

Прикрепите команду и установите оператор Sql

cm.Connection = cn
cm.CommandText = strCommand

Задайте размер выборки. Я использую 4000, потому что он размером с varchar может быть

cm.InitialLONGFetchSize = 4000

Запустите считыватель и пропустите записи/столбцы

dr = cm.ExecuteReader

Do while dr.read()
    strMyLongString = dr(i)
Loop

Вы можете быть более конкретным с чтением, например, dr.GetOracleString(i) dr.GetOracleClob(i) и т.д., если вы сначала идентифицируете тип данных в столбце. Если вы читаете тип данных LONG, тогда простое dr(i) или dr.GetOracleString(i) отлично работает. Ключ должен гарантировать, что InitialLONGFetchSize достаточно большой для типа данных. Также обратите внимание, что родной драйвер не поддерживает CommandBehavior.SequentialAccess для устройства чтения данных, но он вам не нужен, а также поле LONG даже не должно быть последним полем в инструкции select.

Ответ 5

Какой клиент вы используете?.Net, Java, Ruby, SQLPLUS, SQL DEVELOPER? Где вы пишете этот простой оператор select?

И почему вы хотите прочитать содержимое блоба, блоб содержит двоичные данные, чтобы данные не читались. Вы должны использовать clob вместо blob, если хотите сохранить текст вместо двоичного содержимого.

Я предлагаю вам загрузить SQL DEVELOPER: http://www.oracle.com/technetwork/developer-tools/sql-developer/overview/index.html. С SQL DEVELOPER вы можете увидеть содержимое.

Ответ 6

Если вам интересно получить открытый текст (часть тела) от BLOB, вы можете использовать пакет CTX_DOC.

Например, процедура CTX_DOC.FILTER может "генерировать либо простой текст, либо HTML-версию документа". Имейте в виду, что CTX_DOC.FILTER требуется индекс в столбце BLOB. Если вы этого не хотите, вместо этого вы можете использовать процедуру CTX_DOC.POLICY_FILTER, которая не требует индекса.