Что такое код close (blob)


Содержание

ibase_blob_close

ibase_blob_close — Close blob

Описание

This function closes a BLOB that has either been opened for reading by ibase_blob_open() or has been opened for writing by ibase_blob_create() .

Список параметров

Возвращаемые значения

If the BLOB was being read, this function returns TRUE on success, if the BLOB was being written to, this function returns a string containing the BLOB id that has been assigned to it by the database. On failure, this function returns FALSE.

Вытащить BLOB поле

Привет! Помогите пожалуйста, не хватает знаний.

Есть таблица в ней поле определено типа BLOB
В PL\SQL открываю таблицу , двойным кликом по ячейке этого поля открываю окно, там есть перевод в HEX. и там необходимые мне значения!!

Как мне добиться такого же результата в обычном запросе вида
SELECT
FROM
? помогите пожалуйста

25.01.2013, 12:57

Запись в поле с типом данных BLOB
а как можно записать запросом данные в поле с типом BLOB

Как записать Blob поле в DBF таблицу ?
Работаю с ADO, драйвер соединения: ODBC. Создал DBF файл «PR» , в нём поле «Picture» типа.

blob поле
Здравствуйте ! немного непонятно с blob полями.. Пусть есть БД с несколькими таблицами. (см.

Firebird и BLOB-поле
Всем доброго времени суток! Ребята, может кто подскажет в чем подвох. Есть таблица в которой есть.

Поиск и поле blob
Хочу осуществить поиск по таблице по полю Адрес квартиры например, в таблице также к каждой.

CLOSE (BLOB)

Описание

CLOSE закрывает открыт на чтение или вставку BLOB курсор. Вообще BLOB курсор должен быть закрыт только после:

  • Выборка всех сегментов BLOB для операций BLOB READ.
  • Вставки всех сегментов для операций BLOB INSERT.

Эта инструкция может быть использована в SQL.

Синтаксис

Аргумент Описание
blob_cursor Имя открытого BLOB курсора.

Примеры

Следующая внедренная инструкция SQL закрывает BLOB курсор:

Чтение и запись LOB объектов

Вопросам использования больших объектов LOB (Large Object Bynary) зачастую приходится уделять пристальное внимание. Связано это с хранением различных файлов в таблицах базы данных (БД). Сразу же возникает вопрос, зачем хранить в БД файл, если потом придется извлекать его назад опять же в виде в файла? Ведь можно создать отдельное файловое хранилище. Ответ также оказывается простым и тривиальным — для файлового хранилища требуется дополнительно решать вопросы репликации и синхронизации, предоставление прав доступа и создание backup’a. Таким образом, если нельзя обойтись без LOB-объектов, то остается выбрать их тип — бинарный (BLOB Binary Large Object ) или символьный, называемый в БД различных провайдеров по-разному (CLOB, TEXT).

ПРИМЕЧАНИЕ : при работе с символьными данными необходимо учитывать кодировку. Это вопрос будет учтен при записи текстового файла в таблицы БД и выгрузки из БД.

Описание примера

В статье рассматривается пример записи и чтения нескольких типов файлов в поля BLOB и CLOB (TEXT). В качестве серверов БД были использованы Oracle 10g Enterprise Edition, Oracle 10g Express Edition и MySQL 5.1.

Пример представляет собой проект Eclipse, реализующий все принципы ООП (объектно-ориентированное программирование) — наследование, инкапсуляция и полиморфизм. Структура проекта представлена на следующем скриншоте.

В директории «lib» размещаются библиотеки JDBC для подключения к серверам БД. При подключении к серверу 10g Enterprise Edition использовалась библиотека ojdbc7.jar. В случае использования сервера 10g Express Edition были использованы библиотеки ojdbc14_g.jar, ojdbc14.jar. Для подключения в IDE Eclipse библиотеки к проекту необходимо ее выделить и в контекстном меню выбрать «Build Path/Add to Build Path». Чтобы отключить использование библиотеки в проекте используйте вкладку «Java Build Path» в окне свойств проекта.

Пример включает следующие программные модули :

DAOBase.java базовый модуль создания подключения к серверу БД и работы с полями BLOB и CLOB (TEXT);
MainTest.java главный модуль тестирования методов чтения и записи LOB;
MySQLDAO.java модуль создания подключения к серверу MySQL, наследует DAOBase.java;
OracleDAO.java модуль создания подключения к серверу Oracle, наследует DAOBase.java;
Файлы для тестирования aircraft.jpg, отчет.xlsx, текст.txt

Приложение в двух разнотипных БД создает таблицы с полями BLOB и CLOB (TEXT), в которые сначала файлы записываются, потом выполняется их чтение. Представленные процедуры записи и чтения больших объектов Вы можете использовать в своих приложениях практически без доработок.

Создание подключений Connection к различным серверам БД описано здесь и в данной статье не рассматривает (код представлен). Пример можно скачать здесь.

Описание базового модуля, DAOBase.java

Базовый модуль включает следующие основные методы :

Метод Назначение Примечание
public void createConnection() Создание Connection, подключение к БД Переопределяется для каждого провайдера БД
public Connection getConnection() Получение Connection
public void closeConnection() Закрытие Connection
public boolean execSQL (sql) Выполнение SQL-запроса
public boolean writeBlob(table, field, pk, id, fpath) Запись файла в поле BLOB таблицы
public long readBlobToFile(table, field, pk, id, fpath) Извлечение объекта BLOB в файл
public boolean writeClob(table, field, id, fpath) Запись файла в поле CLOB таблицы
public long readClobToFile(table, field, id, path) Извлечение объекта CLOB в файл
public String readClobData(table, field, id) Чтение объекта CLOB

Параметры процедур записи и чтения больших объектов LOB включают наименование таблиц table, наименование LOB-полей field, наименование поля первичного ключа pk, идентификатор записи id и путь к файлу fpath. При необходимости Вы можете доработать данные процедуры и включить в качестве параметра наименование схемы Schema(Oracle) или базы данных Database (MySQL). Не исключено, что и первичный ключ может содержать несколько полей.

ПРИМЕЧАНИЕ :
1. Следует обратить внимание, что методы работы с полями BLOB и CLOB не переопределяются согласно представленной выше таблице. Но это касается баз данных Oracle и MySQL, используемые в примере. Т.е. можно сказать, что методы JDBC «справляются» с полями LOB данных провайдеров. К тому же в MySQL используется тип TEXT, а в Oracle CLOB.
2. Можно использовать различные методы записи в поля LOB содержимое файлов, что будет продемонстрировано на примере MySQL.

Ниже представлен листинг DAOBase.java, где методы работы с полями BLOB и CLOB не включают код. Это сделано преднамеренно для наглядного представления общей структуры модуля DAOBase.java. В противном случае листинг сильно увеличится и «за деревьями нельзя будет увидеть лес». Код методов работы с полями LOB описан далее.

Листинг DAOBase.java

Процедуры создания createTable (sql) и удаления dropTable(sql) таблицы БД не включены в общий список методов DAOBase.java, поскольку в примере выполняют вспомогательную функцию и используется для «подыгрыша». Как правило, структура БД меняется редко и нет необходимости включать в приложение процедуры, которые не используются.

Листинг методов чтения и записи данных в поле BLOB


Две вспомогательные функции readBlobField и writeFromBlob2Stream имеют модификаторы private и используются основным методом readBlobToFile при выгрузке файла из БД.

Для записи файла в поле BLOB используется метод setBinaryStream, получающий в качестве параметра поток FileInputStream. При выгрузке файла из БД в методе readBlobToFile сначала читается объект BLOB (readBlobField), после этого он записывается в выходной поток OutputStream в методе writeFromBlob2Stream, где используется метод чтения в бинарный поток getBinaryStream() объекта BLOB.

Листинг процедур чтения и записи данных в поле CLOB

Две вспомогательные функции readClobField и readFromClob2Stream имеют модификаторы private и используются основными методами readClobToFile, readClobData при выгрузке файла из БД.

Чтобы учесть кодировку символов при записи текстового файла в БД используется InputStreamReader и BufferedReader. Для записи файла в поле CLOB/TEXT используется метод setCharacterStream объекта CLOB, которому передается BufferedReader. При выгрузке файла из БД в методе readClobToFile сначала читается объект CLOB (readClobField ), после этого он записывается в выходной поток BufferedWriter в методе readFromClob2Stream, где используется метод чтения в символьный поток getCharacterStream() объекта CLOB.

Листинг OracleDAO.java

Листинг модуля OracleDAO.java включает переопределенные метод createConnection() и метод создания процедур БД createTable. Структуры таблиц, описанные в константах TABLE_blobs и TABLE_files в виде SQL-скриптов, включают только поля идентификаторов id и поля data соответствующих типов LOB. По умолчанию поля дата имеют значения NULL, поскольку используются в методах при обновлении.

При создании объекта в конструкторе сразу же создается подключение к серверу БД. В качестве свойства объекту подключения передается кодировка устанавливаемого соединения «utf8».

Листинг MySQLDAO.java

Листинг модуля MySQLDAO.java включает переопределенные метод createConnection(), метод создания процедур БД createTable и метод writeClob, который демонстрирует другой подход записи символьного файла в поле TEXT. В данном методе файловый поток FileInputStream сразу же перенаправляется в поток setAsciiStream. Но чтобы не исказить символы использовалась соответствующая кодировка в таблице БД и подключении к серверу. Родительский метод writeClob класса DAOBase.java также сработал без нареканий. Таким образом, в Вашем распоряжении 2 подхода записи текстового файла в БД MySQL.

Структуры таблиц, описанные в константах TABLE_blobs и TABLE_files в виде SQL-скриптов, включают только поля идентификаторов id и поля data соответствующих типов LOB. Для таблицы «files» установлена кодировка «UTF8». По умолчанию поля дата имеют значения NULL, т.к. используются в методах при обновлении.

При создании объекта в конструкторе сразу же создается подключение к серверу БД, которому в качестве свойства передается кодировка устанавливаемого соединения «utf8».

Тестирование примера

Главный модуль приложения MainTest.java выполняет тестирование методов записи файлов в БД и выгрузки в файл. Основной метод тестирования testDAO в качестве параметра принимает базовый класс (полиморфизм). В методе testDAO сначала проверяется установка подключения к серверу БД. Если подключение установлено, то создаются таблицы, в которые записываются и извлекаются файлы.

Результаты тестирования

Приложение выводит сообщения и результатах тестирования методов записи и чтения LOB-объектов в консоль.

Скачать пример

Исходный код рассмотренного примера записи и чтения больших объектов LOB с использованием JDBC можно скачать здесь (7.27 Мб).

При тестировании примера необходимо определить параметры подключения к Вашему серверу БД — схема (база данных), логин и пароль.

Операции над BLOB данными

Interbase поддерживает следующие операции над BLOB данными:

Илон Маск рекомендует:  Простейший способ создания адаптивной шапки

Вставка новой строки включающей BLOB данные

Замена данных ссылающихся на BLOB столбец.

Обновление данных ссылающихся на BLOB столбец.

API Функции динамического SQL (DSQL) и структура данных XSQLD A необходимы, чтобы выполнить SELECT, INSERT, и инструкции UPDATE, требующиеся, чтобы выбирать, вставлять, или модифицировать уместные данные Blob.

6.1.Чтение данных из BLOB.

Эти шесть шагов требуются для чтения данных из существующего BLOB:

1. Создается обычная инструкция SELECT для выбора строки содержащей BLOB столбец.

2. Подготавливается структура для вывода данных XSQLDA.

3. Подготавливается SELECT инструкция.

4. Выполняется инструкция.

5. Выбираем строки одну задругой

6. Читаем и обрабатываем BLOB данные для каждой строки.

Опишем все это подробнее, для непонимающих.

6.2.Создание SELECT инструкции

«SELECT PROJ_NAME, PROJ_DESC, PRODUCT FROM PROJECT WHERE \

PRODUCT IN («software», «hardware»,»other») ORDER BY PROJ_NAME»;

Подготовка структуры вывода XSQLDA

1. Объявляем переменную содержащую XSQLDA

2. Выделяем память

out_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(3));

3.Ставим версию и число выходных параметров

Подготовка SELECT инструкции для выполнения

После создания XSQLDA для содержания данных столбцов каждой выбранной строки,

Строку инструкции нужно подготовить к выполнению.

1. Объявляем и инициализируем дескриптор SQL инструкции,


с помощью известной нам функции isc_dsql_allocate_statement():

isc_stmt_handle stmt; /*Объявление дескриптора инструкции */

stmt = NULL; /* Установка дескриптора в NULL перед выполнением */

3. Подготавливаем строку для выполнения с помощью isc_dsql_prepare(),которая проверяет строку(str) на синтаксические ошибки, переводит строку в формат для эффективного выполнения, и устанавливает в дескриптор инструкции (stmt) ссылку на этот созданный формат (blr что ли). Дескриптор инструкции используется позднее в функции isc_dsql_execute().

Если isc_dsql_prepare()передан указатель на XSQLDA вывода, как в следующем примере, она будет заполнять большинство полей в XSQLDA и всех подструктур XSQLVAR информацией о типа данных, длине, и имени столбца в инструкции.

Пример вызова isc_dsql_prepare():

&trans, /* Устанавливается предварительным вызовом isc_start_transaction()*/

&stmt, /*Дескриптор инструкции устанавливается в вызове этой функции. */

0, /* Определяет что инструкция- строка заканчивается 0*/

str, /* Инструкция — строка */

SQLDA_VERSION1,/* Номер версии XSQLDA */

out_sqlda /* XSQLDA для хранения данных столбцов после выполнения инструкции */

3. Устанавливаем XSQLVAR структуру для каждого столбца:

— Определяем тип столбца ( если он не был установлен isc_dsql_prepare())

— Связываем указатель структуры XSQLVAR sqldata с соответствующей локальной переменной.

Для столбцов чьи типы неизвестных этому моменту:

Приводим элементы типа данных(необязательно), к примеру, из SQL_VARYING к SQL_TEXT.

Динамически выделяем место для хранения данных на которые указывает sqldata

— Определяем число байт данных передаваемых в sqldata

— Предоставляем значение NULL индикатора для параметров

Выбранные данные для Blob (и массивов)столбцов отличаются от других типов столбцов, так что поля XSQLVAR должны быть установлены по-другому. Для не -BLOB (и не массивов) столбцов, isc_dsql_prepare () устанавливают для каждый sqltype к соответствующему типу поля, и выбранные данные помещаются в область памяти на которую указывают соответствующие sqldata, при каждой операции fetch. Для столбцов Blob, тип должен быть установлен в SQL _Blob (или SQL _Blob + 1, если нужен индикатор NULL). InterBase сохраняет внутренний идентификатор Blob (BlobID), а не данные Blob, в памяти на которую кажет sqldata, когда строки данных выбраны, так что sqldata должна указывать на память с размером нужным для хранения BlobID.

Следующий пример кода иллюстрирует назначения для Blob и столбцов не-Blob, чей тип известен ко времени компиляции.

#define PROJLEN 20

#define TYPELEN 12

char proj_name[PROJLEN + 1];

char prod_type[TYPELEN + 1];

short flag0, flag1, flag2;

out_sqlda->sqlvar[0].sqltype = SQL_TEXT + 1;

out_sqlda->sqlvar[1].sqltype = SQL_Blob + 1;

out_sqlda->sqlvar[2].sqltype = SQL_TEXT + 1;

Выполнение инструкции

После того как инструкция подготовлена можно ее выполнить.

&trans, /* Устанавливается предварительным вызовом isc_start_transaction()*/

&stmt, /* выделяется isc_dsql_allocate_statement() */

1, /* XSQLDA version number */

NULL/* NULL так как нет входных параметров */

Эта инструкция создает список выбора, это строки возвращаемые после выполнения инструкции.

6.2.Извлечение выбранных строк

Конструкция цикла извлечения используется, чтобы извлечь(в XSQLDA вывода) данные столбцов для отдельной строки из списка выбора и обработать каждую строку прежде, чем следующая строка будет выбрана. Каждое выполнение isc_dsql_fetch () выбирает данные столбцов соответствующие подструктуры XSQLVAR структуры out_sqlda. Для столбца Blob, выбирается BlobID не являющийся фактическими данными, а просто указатель на них.

isc_dsql_fetch(status_vector, &stmt,1, out_sqlda))

printf(«\nPROJECT: %–20s TYPE:%–15s\n\n»,

/* Read and process the Blob data (seenext section) */

if (fetch_stat != 100L)

/* isc_dsql_fetch returns 100 if no morerows remain to be

Чтение и обработка BLOB данных

Для чтения и обработки BLOB данных


Объявите и инициализируйте BLOB дескриптор

isc_blob_handle blob_handle; /* Объявление BLOB дескриптора. */

blob_handle= NULL; /* Уставите его в NULL перед использованием*/

Создайте буфер для хранения каждого прочитанного BLOB сегмента. Его размер должен быть максимальным размером сегмента в вашей программе используемой для чтения BLOB.

3. Объявите беззнаковую short переменную в которую IB будет хранить фактическую длину каждого прочитанного сегмента:

unsigned short actual_seg_len;

4. Открываем BLOB c извлеченным ранее blob_id

&blob_handle,/*Устанавливается этой функцией для ссылки на BLOB */

&blob_id,/* Blob ID полученный из out_sqlda которую заполнил isc_dsql_fetch() */

0,/* BPB length = 0; фильтр не будем использовать */

NULL/* NULL BPB, фильтр не будем использовать */

5.Читаем все BLOB данные вызывая повторно isc_get_segment(), берущую каждый Blob сегмент и его длину. Обрабатываем каждый прочитаны сегмент.

&blob_handle, /* Устанавливается isc_open_blob2()*/

&actual_seg_len,/* Длина прочитанного сегмента */

sizeof(blob_segment),/* Длина буфера сегмента */

blob_segment/* буфер сегмента */

while (blob_stat == 0 ||status_vector[1] == isc_segment)

/*isc_get_segment возвращает 0 если сегмент был полностью прочитан.

/*status_vector[1] устанавливается в isc_segment только часть */

/*сегмента была прочитана из-за буфера (blob_segment) не являющегося */

/*достаточно большим. В этом случае придется делать дополнительные вызовы */

/*isc_get_segment() для дочитывания. */

printf(«%*.*s»,actual_seg_len, actual_seg_len, blob_segment);

blob_stat =isc_get_segment(status_vector, &blob_handle,

6. Закрываем BLOB

6.2.Запись данных в BLOB

Перед тем как создать новый BLOB и записать туда данные вы должны сделать следующее.

Включить BLOB данные в строку вставляемую в таблицу

Заменить данные ссылающиеся на BLOB столбец строки

Обновить данные ссылающиеся на BLOB столбец строки

Вносимый в столбец Blob фактически не содержит данных Blob. Он содержит BlobID ссылающийся на данные, которые сохранены в другом месте. Так, чтобы установить или изменить столбец Blob, Вы должны установить (или сбросить) BlobID, сохраненный в нем. Если столбец Blob содержит BlobID, и Вы изменяете столбцы относящиеся к различным Blob (или содержащим NULL), Blob на который ссылается предварительно сохраненный BlobID будет удален в течение следующей сборки «мусора».(. )

Все эти операции требуют следующих шагов:

1. Подготовьте соответствующую инструкцию DSQL. Это будет инструкция INSERT, если Вы вставляете новую строку в таблицу, или инструкция UPDATE для изменения строки. Каждая из этих инструкций будет нуждаться в соответствующей структуре ввода XSQLDA для передачи параметров инструкции во время выполнения. BlobID нового Blob будет одним переданных значений

2. Создайте новый BLOB, и запишите в него данные.

3. Свяжите BLOB ID нового BLOB со столбцом таблицы строк над которой вы будете выполнять INSERT и UPDATE.

Примечание: вы не можете непосредственно обновлять BLOB данные. Если вы желаете модифицировать BLOB данные, вы должны:

Создать новый BLOB

Прочитать данные из старого BLOBA в буфер где вы сможете отредактировать и модифицировать их.

Записать измененные данные в новый BLOB.

Подготовить и выполнить инструкцию UPDATE которая модифицирует BLOB столбец содержащий BLOBID нового BLOB, заменяющий старый BLOB ID.

Секция ниже описывает шаги требуемые для вставки, обновления, и замены BLOB данных.

Подготовка UPDATE или INSERT инструкции.

1. Создаем саму строку для обновления

«UPDATE PROJECT SET PROJ_DESC = ? WHERE PROJ_ >

или для вставки

char *in_str = «INSERT INTO PROJECT(PROJ_NAME, PROJ_DESC, PRODUCT,


2. Объявляем переменную содержащую структуру входных параметров

3. in_sqlda = (XSQLDA*)malloc(XSQLDA_LENGTH(2));

4. in_sqlda->version = SQLDA_VERSION1;

5.Установить XSQLVAR структуру в XSQLDA для каждого передаваемого параметра.

Определяем типы данных элементов

Для параметров типы которых известны во время компиляции: указатель sqldata связываем с локальной переменной содержащей передаваемый данные.

Для параметров типы которых неизвестны во время выполнения: выделяем память для хранения данных на которые указывает sqldata

Определяем число байт данных(размер)

Следующий код иллюстрирует все это для столбца BLOB и одного столбца тип данных которого известен во время компиляции.

#define PROJLEN 5

char proj_id[PROJLEN + 1];

in_sqlda->sqlvar[0].sqltype =SQL_Blob + 1;

Proj_id должна быть инициализирована во время выполнения (если значение не известно во времени компиляции). Blob_id должна быть установлена, чтобы обращаться к недавно созданному Blob, как описано в следующих секциях

Создание нового BLOB и хранения данных

1. Объявление и инициализация BLOB дескриптора:

isc_blob_handle blob_handle; /* Объявления BLOB дескриптора */

blob_handle= NULL; /* Устанавливаем дескриптор в NULL перед использованием*/

2. Объявление и инициализация BLOB ID:

ISC_QUAD blob_id; /* Объявление Blob ID. */

3. Создание нового BLOB вызовомisc_create_blob2():

&blob_handle,/* устанавливается этой функцией ссылка на новый Blob */

&blob_id,/* Blob ID устанавливается этой функцией*/

0, /* Blob Parameter Buffer length = 0;no filter will be used*/

NULL /* NULL Blob Parameter Buffer, since no filter will be used*/

Эта функция создает новый BLOB открывает его для записи, и устанавливает blob_handle к указателю на новый BLOB

isc_create_blob2() также связывает BLOB с BLOBID, и устанавливает blob_id к указателю на BLOBID.

4. Записываем все данные, которые будут записаны в Blob, делая ряд вызовов isc_put_segment (). Следующий пример читает строки данных, и связывает каждый Blob с упомянутым blob_handle. (Get_line () читает следующую строку данных, которые будут написаны.)

unsigned short len;

&blob_handle,/* set by previousisc_create_blob2() */

len,/* длина буфера содержащего данные для записи */

line/* буфер содержащий данные для записи в BLOB*/

if (status_vector[0] == 1 &&status_vector[1])

5. Закрываем BLOB

Связывание нового BLOB с BLOB столбцом

Выполнение инструкции UPDATE связывает новый BLOB с BLOB столбцом в строке выбранной инструкции.

6.3.Удаление BLOB

существуют четыре способа удаления BLOB.

Удаляем строку содержащую BLOB. Вы можете использовать DSQL для выполнения DELETE инструкции.

Заменяем различные BLOB. Если Blob столбец содержит BlobID, и вы модифицируете столбец ссылающийся на разные BLOB, ранее сохраненный BLOB будет удален следующей сборкой “мусора”.

Сбрасываем в NULL столбец ссылающийся на BLOB, к примеру, используя DSQL инструкцию как следующую:

UPDATE PROJECT SET PROJ_DESC = NULLWHERE PROJ_

Blob на который указывал удаленный blob_id будет удален следующей сборкой «мусора»

— Отказываемся от BLOB, после того как он был создан но, не был связан еще с определенным столбцом в таблице, используя isc_cancel_blob() функцию.

Запрос информации об открытом BLOB

После того, как приложение открывает Blob, оно может получить информацию о Blob.

Isc_blob_info () позволяет приложению сделать запрос для информации о Blob типа общего количества


числа сегментов в Blob, или о длине, в байтах, самого длинного сегмента. В дополнение к указателю на вектор состояния ошибки и дескриптор Blob, isc_blob_info () требует двух предоставляемых приложением буферов, буфера списков элементов, где приложение определяет информацию, которая требуется, и буфер результатов, куда InterBase возвращает требуемую информацию. Приложение заполняет буфер списков элементов с информационными запросами для isc_blob_info(), и передает ему указатель на буфер списков элементов, а также размер, в байтах, этого буфера.

Илон Маск рекомендует:  Что лучше собрать компьютер самому или купить готовый

Приложение должно также создать буфер результата, достаточно большой, чтобы хранить информацию, возвращенную InterBase. Оно передает указатель на буфер результата, и размер, в байтах, этого буфера в isc_blob_info(). Если InterBase пытается поместить, больше информации чем может вместить буфер результатов, она помещает значение, isc_info_truncated, определенное в ibase.h, в последний байт буфера результатов.

Буфер списка элементов запрашиваемой информации и буфер результатов.

Буфер списка элементов это char массив содержащий запрашиваемые байты значений. Каждый байт есть пункт определяющий тип желаемой информации.

Соответствующие константны определены в ibase.h

#define isc_info_blob_num_segments 4

#define isc_info_blob_max_segment 5

#define isc_info_blob_total_length 6

#define isc_info_blob_type 7

Буфер результатов содержит серию кластеров информации по каждому запрошенному элементу. Каждый кластер содержит три части.

Первый байт определяет тип возвращенной информации.

Второй байт – число определяющее число байт до конца кластера (длина инфо)

Значение хранимое в переменном числе байт, которое интерпретируется в зависимости от типа первого байта кластера

Следующая таблица показывает элементы информацию о которых можно получить

Элемент Возвращаемое значение

Запрашиваемый и возвращаемый элемент

Полное число сегментов

Длина самого длинного сегмента

Полный размер в байтах BLOB

Тип BLOB(0:сегментированный, 1:поток)

В дополнение к этой информации IB возвращенной ответ на запрос, IB может также возвратить один или несколько сообщений состояния в буфер результата. Каждое сообщение состояния есть беззнаковый байт в длине

Результирующий буфер слишком маленький для хранения запрашиваемой информации

Запрашиваемая информация неопеределена. Проверьте status_vector и сообщения.

6.4.Пример вызова isc_blob_info( )

Следующий код запрашивает число сегментов и максимальный размер сегмента для BLOB после открытия, получаемая информация помещается в буфер результатов

char res_buffer[20], *p, item;

SLONG max_size = 0L, num_segments = 0L;

&db_handle, /* database handle, setby isc_attach_database() */

&tr_handle, /* transaction handle, setby isc_start_transaction()

&blob_handle, /* set by thisfunction to refer to the Blob */

&blob_id, /* Blob ID of the Blob toopen */

0, /* BPB length = 0; no filter will beused */

NULL /* NULL BPB, since no filter willbe used */

if (status_vector[0] == 1 &&status_vector[1])

&blob_handle, /* Set inisc_open_blob2() call above. */

sizeof(blob_items),/* Length ofitem-list buffer. */

blob_items, /* Item-list buffer. */

sizeof(res_buffer),/* Length of resultbuffer. */

res_buffer /* Result buffer */

if (status_vector[0] == 1 &&status_vector[1])

/* An error occurred. */

/* Extract the values returned in theresult buffer. */

for (p = res_buffer; *p != isc_info_end;)

length = (short)isc_vax_integer(p, 2);

max_size = isc_vax_integer(p, length);

6.5.Blob дескрипторы


Blob дескриптор используется для предоставления динамического доступа к BLOB информации. К примеру, он может быть использован для хранения информации о BLOB данных для фильтрации, еще как кодовая страница для текстовых BLOB данных и информации о подтипе текстовых данных и не текстовых данных.

Два дескриптора Blob необходимы всякий раз, когда фильтр используется при записи или чтении Blob: один описывать данные источника фильтра, и другой цель.

BLOB дескриптор это структура определенная в заголовочном файле ibase.h как следующая:

short blob_desc_subtype; /* type of Blobdata */

short blob_desc_charset; /* characterset */

short blob_desc_segment_size; /* segmentsize */

unsigned char blob_desc_field_name [32];/* Blob column name */

unsigned char blob_desc_relation_name[32]; /* table name */

Размер сегмента BLOB есть максимальное число байт в приложении

Размер сегмента Blob -максимальное число байтов, которые приложение, как ожидается, запишет или будет читать из Blob. Вы можете использовать этот размер, чтобы выделить ваши собственные буфера. Blob_desc_relation_name и blob_desc_field_name поля содержащие строки с нулевым символом в конце.

Заполнение blob дескриптора

Есть четыре варианта для заполнения blob дескриптора

Вызываем isc_blob_default_desc(). И заполняем ей поля дескриптора значениями по умолчанию. Подтип по умолчанию есть 1 (TEXT), сегмент размером 80 байт, кодовая страница по умолчанию есть страница установленная для вашего процесса.

Вызываем isc_blob_lookup_desc(). Она обращается к системным таблицам и берет оттуда информацию о BLOB и заполняет ею поля дескриптора.

Вызываем isc_blob_set_desc(). Она инициализирует дескриптор из параметров вызова, быстрее нежели получать доступ к метаданным.

Устанавливаем поля дескриптора напрямую.

Следующий пример вызывает isc_blob_lookup_desc () чтобы узнать текущий подтип и информацию о наборе символов для столбца Blob по имени PROJ_DESC в таблице PROJECT. Функция сохраняет информацию в исходном описателе from_desс.

&db_handle; /* Set by previousisc_attach_database() call. */

&tr_handle, /* Set by previousisc_start_transaction() call. */

«PROJECT», /* имя таблицы */

«PROJ_DESC»,/* название столбца */

&from_desc,/* Blob дескриптор заполняется этой функцией. */

&global/* глобальное название колонки возвращаемое этой функцией */

Фильтрация BLOB данных

Фильтр Blob это подпрограмма, которая транслирует данные Blob из одного подтипа в другой.

InterBase включает набор специальных внутренних фильтров Blob, которые преобразовывают подтип 0

( Неструктурные данные) в подтип1 (ТЕКСТ), и из подтипа 1 к подтипу 0.

В дополнение к использованию этих стандартных фильтров, Вы можете создавать ваши собственные внешние фильтры, чтобы обеспечивать специальное конвертирование данных. Например, Вы могли бы разрабатывать фильтр, чтобы преобразовывать один формат изображения к другому, например отображать то же самое изображение на мониторах с различными разрешающими способностями. Или Вы могли бы конвертировать двоичный Blob к простому тексту , чтобы легко файл переносить от одной системы к другой. Если Вы определяете фильтры, Вы можете назначать их идентификаторы подтипа от -32,768 до -1. Следующие разделы дают краткий обзор того, как писать фильтры Blob, и сопровождаются подробностями , как написать приложение, которое требует фильтрации.

Обратите внимание, что фильтры Blob доступны для баз данных, находящихся на всех платформах сервера InterBase кроме Системы Netware, где фильтры Blob не могут быть созданы.

6.6.Использование ваших собственных фильтров

В отличие от стандарта фильтров InterBase, которые конвертируют подтипом 0 в подтип 1 и наоборот, внешний фильтр Blob — вообще часть библиотеки подпрограмм, которые Вы создаете и связываете с приложением. Вы можете писать, Blob на C или Паскаль (или любой язык, который может называться из C).Чтобы использовать ваши собственные фильтры, следуйте по этим шагами:

1. Решите, какой фильтр Вы, должны написать.

2. Напишите фильтры в базовом языке.

3. Сформируйте общедоступную библиотеку фильтров.

4. Сделайте библиотеку фильтров доступной.

5. Определить фильтры для базы данных.

6. Напишите приложение, которое требует фильтрацию.

Шаги 2, 5 и 6 будут лучшеописаны в следующих разделах.

6.7.Объявление внешнего фильтра BLOB для БД

Для объявления внешнего фильтра для БД, используйте инструкции DECLARE FILTER. К примеру, следующая инструкция объявляет фильтр, SAMPLE:

DECLARE FILTER SAMPLE

INPUT TYPE –1 OUTPUT_TYPE –2

ENTRY POINT «FilterFunction»

В примере, входной подтип фильтра определен как -1 и его выходной подтип как -2. Если подтип -1определяет текст нижнего регистра, а подтип -2 текст верхнего регистра, то цель фильтра SAMPLE состояла бы в том, чтобы перевести данные Blob из текста нижнего регистра в текст верхнего регистра.

Параметры ENTRY_POINT И MODULE_NAME определяют внешнюю подпрограмму, которую вызывает, когда вызывается фильтр. Параметр MODULE_NAME определяет filter.dll, динамически загружаемую библиотеку, содержащую выполнимый код фильтра. Параметр ENTRY_POINT определяет точку входа в DLL. Хотя пример показывает только простое имя файла, это — хорошая практика для определения полного квалифицированного пути, начиная с пользователей вашего приложения желающих загрузить файл.

6.8.Создание внешних Blob фильтров


Если Вы хотите создавать ваши собственные фильтры, Вы должны иметь детальное понимание типов данных , которые Вы планируете конвертировать. InterBase не делает строгой проверки типа данных на данные Blob; это — ваша ответственность.

Определений функций фильтров

При написании фильтра, Вы должны включить точку входа, известной функции фильтра, в секции объявления программы. InterBase вызывает функцию фильтра, когда приложение выполняет операции на Blob, определенные для использования фильтра. Вся связь между InterBase и фильтром происходит через функцию фильтра. Функция самого фильтра может вызывать другие функции, которые включает исполняемая программу фильтра.

Вы объявляете имя функции фильтра и имя выполняемой программы — фильтра с параметрами ENTRY_POINT И MODULE_NAME в инструкции DECLAREFILTER.

Функция фильтрадолжна иметь следующее объявление, вызывающее последовательность:

filter_function_name(short action, isc_blob_ctl control);

Параметр, action, является одним из восьми возможных макроопределений действия, и параметр, control- элемент isc_blob_ctl, управляющей структуры Blob, определенной в файле заголовка InterBase, ibase.h. Эти параметры обсуждаются позже в этой главе.

Следующий листинг скелетного фильтра описывает функцию фильтра, jpeg_filter:

#define SUCCESS 0

#define FAILURE 1

ISC_STATUS jpeg_filter(short action, isc_blob_ctl control)

ISC_STATUS status = SUCCESS;

InterBase передает одно из восьми возможных действий к функции фильтра, jpeg_filter, посредством параметра action, и также передает экземпляр управляющей структуры Blob, isc_blob_ctl, посредством параметра, control. ellipses (…) в предыдущем листинге представляют код, который выполняет некоторые операции, для каждого действии, или случая, который перечислен в инструкции case.

6.9.Определение управляющей структуры BLOB

Управляющая структура BLOB предоставляет основные методы обмена данными между фильтром и Interbase.

Управляющая структура BLOB определена при помощи typedef, isc_blob_ctl. в ibase.h вот так:

typedef struct isc_blob_ctl <

/* Указатель на внутреннюю InterBase Blob подпрограмму доступа.(функтор) */

struct isc_blob_ctl *ctl_source_handle;

/* Экземпляр ofisc_blob_ctl передаваемый во внутреннюю подпрограмму доступа IB*/

short ctl_to_sub_type;/* Целевой подтип */

short ctl_from_sub_type;/* Исходный подтип */

unsigned short ctl_buffer_length; /* Длина ctl_buffer. */

unsigned short ctl_segment_length; /* Длина текущего сегмента */

unsigned short ctl_bpb_length; /* Длина буфера параметров BLOB. */

char *ctl_bpb; /* Указатель на буфер параметров BLOB */

unsigned char*ctl_buffer; /* Указатель на сегментный буфер */

ISC_LONGctl_max_segment; /* Длина самого длинного BLOB сегмента */

ISC_LONGctl_number_segments; /* Полное число сегментов */

ISC_LONGctl_total_length; /* Полная длина BLOB*/

ISC_STATUS*ctl_status;/* Указатель на статус вектор */

long ctl_data[8];/* Данные определяемые приложением */

Семантика некоторых isc_blob_ctl полей зависит от выполняемого действия.

Например, когда приложение вызывает isc_put_segment () функцию API, InterBase передает isc_blob_filter_put_segment — действие функции фильтра. Буфер, указатель на буфер, ctl_buffer — поле управляющей структуры, передаваемый функции фильтра, содержит сегмент данных, которые будут записано, как определено приложением в его запросе к isc_put_segment (). Поскольку буфер содержит информацию, передаваемую в функцию фильтра, это называется полем IN. Функция фильтра должна включить инструкции в инструкцию case под isc_blob_filter_put_segment для выполнения фильтрации и затем передачи данных для записи в базу данных. Это может быть сделано, вызовом *ctl_source подпрограммы доступной внутри Interbase подпрограммы. Для подробной информации относительно ctl_source, см. Руководство Программиста.

С другой стороны, когда приложение вызывает isc_get_segment () функцию API, и буфер, на него указывает ctl_buffer в управляющей структуре переданной функции фильтра, пуст. В этом случае, InterBase передает isc_blob_filter_get_segment действие- функции фильтра. Обработка действия- функции isc_blob_filter_get_segment фильтра должна включить команды для заполнения ctl_buffer сегментом данных из базы данных, чтобы возвратить его приложению. Это может быть сделано, вызовом *ctl_source подпрограммы доступной внутри IB. В этом случае, буфер используется для вывода информации функцией фильтра, и называется полем OUT.

Следующая таблица описывает каждое из полей в isc_blob_ctl управляющей структуре Blob, используются ли они для ввода функции фильтра (IN), или вывода (OUT).

convert blob to clob

I’m using oracle 11g and I’m trying to find out the length of a text. I will normally use select length(myvar) from table, but I can’t do that.

Илон Маск рекомендует:  Что такое код delphixml

The table which I want to query has a BLOB column that saves characters or photos. I want to know the number of characters that have my BLOB column.

I tried to convert my BLOB into a char using UTL_RAW.CAST_TO_VARCHAR2(myblob) from table, but this functions isnt’t working correctly or maybe I’m making a mistake.

For example: My BLOB have the word Section, when I see this in the databse in the hexadecimal form I see S.e.c.t.i.o.n.. I dont’k know why it have those points in between each letter. Then I used the this query

The result of this query is ‘S’ so it’s not the complete word that my BLOB has, and when I make this query

the result is 18 and the word Sections doesn’t have 18 characters.

I was trying to convert the blob into a varchar, although I think my best choise would be a clob because the length of the text that it can save is more than the limit that varchar has. I tried to do that by making this query (I’m not sure if this is correct but is what I found in the internet)

This query also returns ‘S’

I hope you can help me with this problem. thanks for advanced


Как получить текстовое содержимое из BLOB в Oracle SQL

Я пытаюсь увидеть из консоли SQL то, что находится внутри Oracle BLOB.

Я знаю, что он содержит несколько большую часть текста, и я хочу просто увидеть текст, но следующий запрос указывает только, что в этом поле есть BLOB:

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

Итак, какие магические заклинания я могу сделать, чтобы превратить BLOB в это текстовое представление?

PS: Я просто пытаюсь посмотреть содержимое BLOB с консоли SQL (Eclipse Data Tools), а не использовать его в коде.

Прежде всего, вы можете захотеть сохранить текст в столбцах CLOB/NCLOB вместо BLOB, который предназначен для двоичных данных (ваш запрос будет работать с CLOB, кстати).

Следующий запрос позволит вам увидеть первые 32767 символов (максимум) текста внутри blob, если все наборы символов совместимы (исходная CS текста, хранящегося в BLOB, CS базы данных, используемой для VARCHAR2 ):

Вы можете использовать ниже SQL для чтения BLOB-полей из таблицы.

Работа с полями типа BLOB

Поля BLOB (Binary Large Object) разработаны для размещения в них данных неоп ределенного размера. Поля BLOB в одной записи набора данных могут содержать 3 байта данных, в то время как подобное же поле в другой записи может содержать

3 Кбайта данных. Эти поля наиболее удобны для хранения большого количества тек

ста, графики либо таких непредсказуемых типов данных, как объекты OLE.

Класс TBlobField и типы полей

Как уже отмечалось в этой главе, в библиотеке VCL существует класс TBlobField, производный от класса TField и специально предназначенный для инкапсуляции полей BLOB. Класс TBlobField содержит свойство BlobType типа TBlobType, которое ото бражает, какой именно тип данных хранится в его поле BLOB. Тип TBlobType определен в модуле DB следующим образом:

Все возможные типы объектов и данных, которые может принимать поле BLOB, приведены в табл. 7.4.

Таблица 7.4. Типы полей класса TBlobField

Тип поля Тип данных

ftBlob Нетипизированные или определенные пользователем данные

ftGraphic Растровая графика Windows ftFmtMemo Поле MEMO в формате Paradox ftParadoxOle Объект OLE

ParadoxОкончание табл. 7.4.

Тип поля Тип данных

ftDBaseOLE Объект OLE dBASE

ftTypedBinary Любые неструктурированные данные

ftCursor..ftDataSet Недопустимые типы BLOB ftOraBlob Поля BLOB таблиц Oracle8 ftOraClob Поля CLOB таблиц Oracle8

Как правило, основная часть работы по выборке и помещению данных в компо нент класса TBlobField может быть выполнена при их загрузке или сохранении в файле либо с помощью компонента класса TBlobStream. Класс TBlobStream являет ся специализированным, производным от класса TStream, который использует поле BLOB внутри физической таблицы как место размещения потока. Для демонстрации методов взаимодействия с компонентом класса TBlobField создадим демонстраци онное приложение.

Пример использования поля BLOB

В описанном далее проекте создается приложение, которое позволяет пользователю сохранять звуковые файлы (.wav) в таблице базы данных, а затем воспроизводить их непосредственно из этой таблицы. Начните проект с создания главной формы с компо нентами, показанными на рис. 7.9. Компонент TTable может описывать таблицу Wavez, расположенную в соответствии с псевдонимом DDGUtils, или вашу собственную табли цу с подобной структурой. Структура таблицы Wavez приведена ниже.

Рис. 7.9. Главная форма для таблицы

Wavez — примера использования поля BLOB

Кнопка Add используется для загрузки звукового файла с диска и добавления его в таблицу. Подпрограмма обработки события OnClick кнопки Add имеет следующий вид:

procedure TMainForm.sbAddClick(Sender: TObject);

if OpenDialog.Execute then begin

В этой процедуре сначала предпринимается попытка выполнить метод OpenDia- log. Если такая операция выполняется успешно, то источник данных tblSound пе реключается в режим Append, полю FileName присваивается значение и поле типа BLOB по имени Wave заполняется данными из файла, определенного параметром OpenDialog. Обратите внимание, насколько удобно использовать здесь метод Load- FromFile класса TBlobField и как просто выглядит код загрузки файла в поле BLOB.

Подобным же образом щелчок на кнопке Save приводит к сохранению во внеш

нем файле содержимого звукового файла, расположенного в поле Wave. Код процеду

ры для этой кнопки выглядит следующим образом:

procedure TMainForm.sbSaveClick(Sender: TObject);

with SaveDialog do begin

Получить имя файла

if Execute then

Сохранить blob в файл

В данном методе используется еще меньше кода. Объект SaveDialog инициали зируется значением поля FileName. Если процедура SaveDialog выполняется ус пешно, то для сохранения содержимого поля BLOB в файле вызывается метод Save- ToFile объекта tblSoundsWave.

Обработчик кнопки Play считывает звуковые данные из поля BLOB и передает их функции API PlaySound() для воспроизведения. Код этого обработчика приведен ни же. Обратите внимание, что данный код немного сложнее приведенного выше кода для кнопки Save.

procedure TMainForm.sbPlayClick(Sender: TObject);

// Создание потока BLOB


B := TBlobStream.Create(tblSoundsWave, bmRead);

Screen.Cursor := crHourGlass; // Отображение песочных часов

M := TMemoryStream.Create; // Создание потока памяти

// Копирование из потока BLOB в поток памяти

// Попытка воспроизвести звук. Передача исключения,

// если что-нибудь будет не так, как надо.

Win32Check(PlaySound(M.Memory, 0, SND_SYNC or SND_MEMORY));

B.Free; // Освобождение памяти

Сначала этот метод создает экземпляр класса TBlobStream по имени B, используя поле BLOB таблицы tblSoundsWave. Первый параметр, передаваемый методу TBlob- Stream.Create(), является объектом поля BLOB, а второй параметр указывает, как следует открыть поток. Обычно к потоку BLOB обращаются только для чтения, исполь зуя значение bmRead, а для записи используют значение bmReadWrite.

Чтобы открыть поток TBlobStream с параметром bmReadWrite используемый набор данных должен быть переведен в режим Edit, Insert или Append.

Затем создается экземпляр M класса потока TMemoryStream. В этот момент обычный указатель мыши изменяется на изображение песочных часов, что указывает пользователю на продолжительность выполняемой операции. Затем поток B копируется в поток M. Функции PlaySound(), применяемой для воспроизведения звукового файла, в качестве первого параметра должно быть передано имя файла или указатель на область памяти. Класс TBlobStream не предоставляет доступа к данным потока с помощью указателя, а класс TMemoryStream обеспечивает такую возможность с помощью свойства Memory. Воспользовавшись этим, можно вызвать функцию PlaySound() для воспроизведения данных, указатель на которые содержится в свойстве M.Memory. После завершения рабо ты этой функции необходимо освободить потоки и восстановить вид указателя мыши. Полный код основного модуля данного проекта приведен в листинге 7.4.

Листинг 7.4. Основной модуль проекта Wavez

unit Main; interface uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

Dialogs, ExtCtrls, DBCtrls, DB, DBTables, StdCtrls, Mask,

OpenDialog: TOpenDialog;tblSoundsFileName: TStringField; SaveDialog: TSaveDialog; pnlToobar: TPanel;

sbPlay: TSpeedButton; sbAdd: TSpeedButton; sbSave: TSpeedButton; sbExit: TSpeedButton; Bevel1: TBevel;

procedure sbPlayClick(Sender: TObject);

procedure sbAddClick(Sender: TObject);

procedure sbSaveClick(Sender: TObject);

procedure sbExitClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure FormClose(Sender: TObject;

var Action: TCloseAction);

procedure OnAppHint(Sender: TObject);

procedure TMainForm.sbPlayClick(Sender: TObject);

// Создать поток blob

B := TBlobStream.Create(tblSoundsWave, bmRead);

Screen.Cursor := crHourGlass; // песочные часы

M := TMemoryStream.Create; // Создать поток в памяти

// Копирование из потока BLOB в поток памяти

// Попытка воспроизвести звук. Передача исключения,

Что это такое BLOB в контексте СУБД

BLOB (Binary Large Object) — это большой тип данных объекта в системе базы данных. BLOB может хранить большой фрагмент данных, типов документов и даже медиафайлов, таких как аудио- или видеофайлы. Поля BLOB выделяют пространство только тогда, когда используется контент в поле. BLOB выделяет пробелы в байтах Giga.

Вы можете записать двоичный большой объект ( BLOB ) в базу данных как двоичные или символьные данные, в зависимости от типа поля в вашем источнике данных. Чтобы записать значение BLOB в вашу базу данных, введите соответствующий оператор INSERT or UPDATE и передайте значение BLOB в качестве входного параметра. Если ваш BLOB хранится как текст, например текстовое поле SQL Server, вы можете передать BLOB в качестве строкового параметра. Если BLOB хранится в двоичном формате, таком как поле изображения SQL Server, вы можете передать массив байтов типа как двоичный параметр.

Я не буду расширять аббревиатуру еще раз. но я добавлю некоторые нюансы к другому определению: вы можете хранить любые данные в блоке независимо от других интерпретаций байтов, которые они могут иметь. Текст может быть сохранен в блобе, но вам будет лучше с CLOB, если у вас есть эта опция.

Между BLOBS между базами данных не должно быть различий в том смысле, что после того, как вы сохранили и извлекли данные, они остались неизменными. как каждая база данных достигает черных ящиков и, к счастью, почти без исключения не имеет значения. Способ взаимодействия с BLOBS, однако, может сильно отличаться, поскольку для него нет спецификаций в стандартах SQL (или стандартах в спецификациях?). Обычно вам нужно будет вызывать процедуры/функции, чтобы сохранить их, и ограничение любого запроса, основанного на содержимом BLOB, практически невозможно, если не запрещено.

Среди других материалов, перечисленных как двоичные данные, вы также можете хранить двоичные представления текстовых кодов символов с заданным кодированием. без фактического знания или определения используемой кодировки.

BLOBS — это самые низкие общие знаменатели форматов хранения.

ibase_blob_close

ibase_blob_close — Close blob

Açıklama

This function closes a BLOB that has either been opened for reading by ibase_blob_open() or has been opened for writing by ibase_blob_create() .

Değiştirgeler

Dönen Değerler

If the BLOB was being read, this function returns TRUE on success, if the BLOB was being written to, this function returns a string containing the BLOB id that has been assigned to it by the database. On failure, this function returns FALSE .

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL