Категории
Самые читаемые
Лучшие книги » Компьютеры и Интернет » Программирование » Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil - А Ковязин

Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil - А Ковязин

Читать онлайн Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil - А Ковязин

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 51 52 53 54 55 56 57 58 59 ... 112
Перейти на страницу:

Единственным ограничением, которое присутствует в текущей версии IBProvider (1.6.2), является невозможность редактирования выбранного множества строк, т. е. работы с так называемыми "живыми" запросами, которые часто используются в приложениях, создаваемых с помощью средств разработки компании Borland.

Практическое использование IBProvider

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

IBProvider предоставляет поддержку двум типам BLOB-полей: содержащих текст (SUB_TYPE TEXT) и бинарные данные. При этом доступ к BLOB может быть организован как к данным в памяти, так и к объекту-хранилищу. В любом случае провайдер не хранит сами данные BLOB-поля, а каждый раз загружает их по требованию клиента.

ADODB. Чтение BLOB:

Dim cn As New ADODB.Connection

cn.Open "file name=d:databaseemployee.ibp"

cn.BeginTrans

Dim cmd As New ADODB.Command

Dim rs As ADODB.Recordset

cmd.ActiveConnection = cn

'JOB_REQUIREMENT - текстовое BLOB-поле

cmd.CommandTexc = "select nob_requirement from job"

Set rs = cmd.Execute

'доступ к BLOB как к данным в памяти

While Not rs.EOF

'печатаем размер BLOB-поля. обращение к ActualSize

'не производит загрузки самих данных

Debug.Print "size:" & CStr(rs(0).ActualSize)

If IsNull(rs(0)) Then

Debug.Print "NULL"

Else

Debug.Print rs(0)

End If

rs.MoveNext

Wend

Debug.Print "******************"

rs.MoveFirst

'чтение порциями по 40 байт

Dim seg As Variant, str As String

Const seg_size = 40

While Not rs.EOF

'пропускаем пустые BLOB-поля

If (Not IsNulKrs(0))) Then

str = ""

Do

seg = rs(0).GetChunk(seg_size)

'когда данных нет - GetChunk возвращает NULL

If IsNull(seg) Then Exit Do

str = str + seg

Debug.Print "get chunk: " & Len(seg) & " bytes"

Loop While True

Debug.Print ">" & CStr(rs(0).ActualSize) & " - " & Len(str)

Debug.Print ">" & str

End If

rs.MoveNext

Wend

cn.CommitTrans

ADODB. Запись BLOB-поля:

Dim cn As New ADODB.Connection

cn.Open "file name=d:databaseemployee.ibp"

cn.BeginTrans

Dim cmd As New ADODB.Command

Dim rs As ADODB.Recordset

cmd.ActiveConnection = cn

'JOB_REQUIREMENT - текстовое BLOB-поле

cmd.CommandText = "select * from job"

Set rs = cmd.Execute

Dim upd_cmd As New ADODB.Command

upd_cmd.ActiveConnection = cn

upd_cmd.CommandText = _

"update job set job_requirement=? " & _

"where job_code=? and job_grade=? and " & _

"job_country=?"

upd_cmd.Parameters.Refresh

Dim RowAffected As Long

While Not rs.EOF

If (Not IsNull(rs("job_requirement"))) Then

upd_cmd(0) = UCase(rs("job_requirement"))

upd_cmd(l) = rs("job_code")

upd_cmd(2) = rs("job_grade")

upd_cmd(3) = rs("job_country")

upd_cmd.Execute RowAffected

Debug.Print "affect:" & CStr(RowAffected)

End If

rs.MoveNext

Wend

'отменяем все изменения в базе данных

cn.RollbackTrans

Работа с BLOB-полями через TBProvider на C++ также прозрачна. Хотя можно написать более интересные алгоритмы, например подстановка объекта-хранилища, полученного из результирующего множества, в качестве параметра в команду, привязанную к другой базе данных. Подробности см. в примерах из дистрибутива IBProvider и спецификации OLEDB - "BLOB's and OLE Objects".

Работа с массивами

Встроенная поддержка массивов является одним из основных пунктов списка достоинств InterBase как SQL сервера баз данных. И одновременно массивы возглавляют список его невостребованных возможностей. В практике сильная потребность в использовании массивов возникала только один раз. Эта работа была связана с анализом накапливаемой информации, касающейся функционирования торговой организации. Тогда основным препятствием оказалось отсутствие готового решения для работы с массивами InterBase из VBA (MS Office).

Поэтому в IBProvider была реализована поддержка массивов с предоставлением высокоуровневого представления этого несомненно полезного типа данных InterBase.

Особенности реализации поддержки массивов

* OLEDB-спецификация для представления типа данных "массив" использует структуру SAFEARRAY. Эта же структура употребления для управления массивами в Visual Basic.

* Элементы массивов не могут содержать NULL. Это ограничение связано с тем, что InterBase не поддерживает тип VARIANT.

* Все типы строк, хранящиеся в массивах, обрабатываются сервером как Си- строки, т. е. заканчивающиеся нулем. IBProvider исходит именно из такого способа хранения и не использует собственных символов типа п для определения конца строки.

* Провайдер предоставляет полную поддержку для преобразования массивов из одного типа в другой. И пользуется ею по умолчанию, поскольку VB не понимает структуру SAFEARRAY, содержащую данные, несовместимые с VARIANT. Вообще говоря, наверное, можно было бы всегда возвращать массивы, содержащие VARIANT, но удалось обойтись без этой крайности. Отключить конвертирование массивов можно с помощью свойства инициализации источника данных (строка подключения) или набора строк "array_vt_type", установив его значение в false.

* Как и BLOB-поля, провайдер не хранит и не кеширует данные массива. Информация каждый раз загружается с сервера.

* Если при чтении массивов от пользователя не требуется никакой помощи, то для записи массивов провайдеру может потребоваться дополнительная информация. Дело в том, что запись массива, как и BLOB-поля, производиться отдельным обращением к InterBase API. Для этой операции требуется иметь описание, содержащее имя таблицы и имя колонки, в которую производится запись, тип элемента и сведения о размерности. Провайдер способен самостоятельно определить эту информацию только при работе с сервером InterBase 6.x и выше. Для работы с InterBase 4.x и InterBase 5.x IBProvider вводит нестандартное расширение, позволяющее определять в тексте запроса параметры вида "параметр.таблица.колонка". Этот синтаксис может быть использован как для именованных, так и для неименованных параметров:

update job set language_req=?.job.language_req

update job set language_req=:param.job.language_req

Переданные таким образом названия таблицы и колонки используются только для внутренних целей и недоступны вне провайдера. Если IBProvider смог самостоятельно получить эту информацию или значение параметра не является массивом, то пользовательская помощь игнорируется. В противном случае клиент отвечает за корректность переданных дополнительных сведений о параметре. Дополнительно заметим, что во 2-й и 3-й части такого составного имени параметра можно использовать квотированные названия объектов базы данных.

* Клиент не имеет возможности определить интересующее его подмножество массива. Провайдер всегда возвращает массив целиком. Это ограничение OLEDB, а не InterBase.

* При записи массива можно передавать подмножество. Но нужно учитывать, что массив всегда пересоздается. Поэтому в случае выполнения "UPDATE...", можно потерять предыдущую информацию из неуказанных элементов.

Пример чтения массивов.:

ADODB

Dim en As New ADODB.Connection

cn.Open "file name=d:databaseemployee.ibp"

Dim cmd As New ADODB.Command, rs As ADODB.Recordset

cmd.ActiveConnection = cn

cmd. CornmandText = "select * from proj_dept_budget"

Set rs = cmd.Execute

Dim qhc As Variant ' QUART_HEAD_CNT

Dim i As Long

While Not rs.EOF

If IsNull(rs("quart_head_cnt")) Then

Debug.Print "NULL"

Else

qhc = rs("quart_head_cnt")

For i = LBound(qhc, 1) To UBound(qhc, 1)

Debug.Print "qhc[" & CStr(i) & "]=" & CStr(qhc(i))

Next i

End If

rs.MoveNext

Debug.Print "-------------------"

Wend

Пример записи массивов (InterBase 5.6):

ADODB

Dim en As New ADODB.Connection

cn.Open "file name=d:databaseemployee.ibp"

Debug.Print en.Properties("IB Version")

cn.BeginTrans

Dim cmd As New ADODB.Command, rs As ADODB.Recordset

cmd.ActiveConnection = cn

cmd CommandText = "select * from proj_dept__budget"

Set rs = cmd.Execute

Dim upd_cmd As New ADODB.Command

upd_cmd.ActiveConnection = cn

upd_cmd.CommandText = _

"update proj_dept_budget " & _

"set quart_head_cnt=:a pro]_aept_budget.quart_head_cnt " & _

"where year=:year and proj_id=:proj_id and dept_no=:dept_no"

upd_cmd.Parameters.Refresh

Dim qhc As Variant ' QUAD_HEAD_CNT

Dim i As Long, RowAffected As Long

While Not rs.EOF

If Not IsNull(rs("quart_head_cnt")) Then

qhc = rs("quart_head_cnt")

For i = LBound(qhc, 1) To UBound(qhc, 1)

qhc(i) = 10 * qhc(i)

Next i

upd_cmd("a") = qhc

upd_cmd("year") = rs("year")

upd_cmd ("proj_id" ) = rs ("proj_id")

upd_cmd("dept_no") = rs("dept_no")

upd_cmd.Execute RowAffected ' транзакционные изменения

Debug.Print ">" & CStr(RowAffected)

End If

rs.MoveNext

Debug.Print -------------------

Wend

en.CommitTrans

Работа с хранимыми процедурами

Хранимые процедуры делятся на две категории - селективные (процедуры- выборки) и исполняемые.

Принцип работы с селективной хранимой процедурой, возвращающей ре- з>льтат своей работы в виде набора строк, очень похож на выполнение обычного SQL-запроса "SELECT..." содержащего параметры.

Вызов селективной процедуры "SUB_TOT_BUDGET"

ADODB

'вспомогательная функция конвертирования VARIANT в строку

'с поддержкой NULL

Function my_cstr(s As Variant) As String

If (IsNull(s)) Then

my_cstr = "NULL"

Else

my_cstr = CStr(s)

End If

End Function

Sub sproc_select()

Dim cn As New ADODB.Connection

cn.Open "file name=d:databaseemployee.ibp"

cn.BeginTrans

Dim cmd As New ADODB.Command

cmd.ActiveConnection = cn

cmd.CommandText = "select * from SUB_TOT_BUDGET(?)"

cmd(0) = 100

Dim rs As ADODB.Recordset

Set rs = cmd.Execute

Dim col As Long

While Not rs.EOF

Debug.Print "----------------"

For col = 0 To rs.Fields.Count - 1

Debug.Print CStr(col) & ":" & rs.Fields(col).Name & " - " &

my_cstr(rs(col})

Next col

rs.MoveNext

Wend

cn.CommitTrans

End Sub

Вызов исполняемой ХП отличается от использования селективной ХП в том плане, что применяют SQL-запрос EXECUTE PROCEDURE... и получают результат работы через out-параметры. IBProvider различает только вызов исполняемой ХП, анализируя сигнатуру SQL-запроса. Наряду с SQL-выражением EXECUTE PROCEDURE..., непосредственно поддерживаемого InterBase, в тексте команды можно указывать EXECUTE ... и ЕХЕС ... IBProvider распознает в этих командах попытку вызова исполняемой ХП и автоматически приводит текст SQL-запроса к совместимому с InterBase. Для получения результата работы исполняемой ХП нужно либо самостоятельно описать out-параметры, либо попросить команду сформировать эти описания самостоятельно (ADODB Command Paiameters.Refresh). Основными правилами здесь являются:

1 ... 51 52 53 54 55 56 57 58 59 ... 112
Перейти на страницу:
На этой странице вы можете бесплатно скачать Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil - А Ковязин торрент бесплатно.
Комментарии