Выбрать главу

<input type=text name='b_theme' size=16 maxlength=60></td></tr>");

printf ("<trxtd colspan=2 align=right>

<input type= ' submit' value='Add data'></td></tr>"};

printf ("</table></form></td></tr></table></center></body></html>");

return(0);

}// end of main

Вот что мы получим при первом запуске приложения при пустой таблице данных (см. рис 3.2):

Рис 3.2. Результат вставки записи

После вставки какой-нибудь записи в таблицу при помощи формы справа снизу результат будет следующим (см. рис 3.3).

Рис 3.3. Результаты выполнения CCI-приложения

В этом приложении читается несколько переменных www-окружения, которые проверяются на ненулевую длину и передаются в качестве входящего параметра запроса. Переменные www-окружения читаются при помощи функций библиотеки CGIC (ее можно загрузить с сайта http://www.boutell.com/cgic), однако вы можете воспользоваться любой удобной вам библиотекой. В качестве результата анализируется переменная res_code, и в зависимости от ее значения сообщается результат вызова процедуры. Неизвестные входные параметры, участвующие в запросе, передаются следующим образом: на местах неизвестных параметров ставится знак вопроса (?), а в соответствующей этому параметру переменной XSQLDA определяется тип и данные для передаваемой переменной, причем допускается смешивать родственные типы (int-smallint, char-varchar и т д ) При внимательном изучении примера видно, что запрос, выбирающий данные из таблицы, вызывается несколько отличным методом, нежели запрос вызывающий ХП. Первый запрос, состоит из следующих этапов:

* Резервирование ресурсов, требуемых для запроса библиотекой доступа к InterBase, - вызов функции isc_dsql_allocate_statement().

* Подготовка запроса к исполнению сервером - именно на этом этапе выдаются сообщения об ошибках в синтаксисе - вызов функции isc_dsql_prepare().

* Исполнение запроса сервером - вызов функции isc_dsql_execute2() (или isc_dsql_execute(), отличие этих функций в том, что вызов isc_dsql_execute() непременно требует вызова функции isc_dsql_fetch(), если существуют исходящие параметры). На этом этапе могут быть выданы сообщения о несоответствии типов и/или количества элементов XSQLDA.

* Доставка данных приложению - вызов isc_dsql_fetch(). В отличие от большинства остальных API-функций эта функция возвращает целое число, содержащее код ошибки, - пока это значение равно нулю, данные есть и их можно прочитать. Когда выбраны все данные, это значение становится отличным от нуля.

* Освобождение ресурсов, занятых на этапе 1, - вызов isc_dsql_free_statement(). Инициализация структур XSQLDA обычно происходит до п. 2.

Второй запрос исполняется сразу, минуя все вышеперечисленные пункты, кроме п. 3. В данном случае используется функция isc_dsql_exec_immed2(). Отличие данных методов заключается в том, что в случае первого запроса можно воспользоваться пп. 3 и 4 внутри цикла - это дает преимущество в скорости, при исполнении одного и того же запроса, но с разными значениями параметров, так как синтаксис уже проверен и запрос сразу исполняется. Метод, реализованный в исполнении второго запроса, обычно применяется при однократном вызове хранимых процедур или при исполнении команд, которые разрешается исполнять только в этих функциях (например, CREATE DATABASE разрешается использовать только в вызове функции isc_dsql_execute_immediate()).

Так как в случае "немедленного" исполнения запроса не происходит его предварительного анализа, то необходимо инициализировать переменную sqld структуры XSQLDA, которая используется для получения результата (в данном случае это делает строка osqlda -> sqld =1). Если не проинициализировать эту переменную, то в качестве результата вызова функции isc_dsql_exec_immed2 будет получена ошибка Message length error... По той же причине, необходимо явно указывать размер памяти, который будет занимать переменная, хранящая результат, - в данном случае это sizeof(long). Если этого не сделать, то последствия будут непредсказуемы, - в лучшем случае вы не получите ничего на выходе.

При разработке CGI-приложений, работающих с InterBase, следует придерживаться следующих правил:

* Все переменные www-окружения должны быть проанализированы до подключения к базе данных - может случиться, что нужных данных нет или они не удовлетворяют каким-либо требованиям и работа с базой данных заведомо теряет смысл. В этом случае следует проинформировать пользователя о неверно введенных данных.

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

* Запускайте, если это возможно, сервер от имени пользователя с ограниченными правами.

* Создайте клиента базы данных (см. главу "Безопасность в InterBase: пользователи, роли и права" (ч. 4)), которого будут использовать все www-приложения для доступа к базе данных, и назначьте ему минимально необходимые права.

Маленький совет напоследок (применимый для InterBase с архитектурой SuperServer): если прописать вызов сервера в inittab с параметром respawn, то система сама перезапустит сервер в случае его падения надежнее, чем это сделает guardian Таким образом, получится некий аналог птицы Феникс - сервер базы данных возродится сразу же после фатальной ошибки (допущенной, например, при разработке приложений на API).

Заключение

Несмотря на устрашающий размер примеров, в работе с базами данных InterBase и его клонов на уровне API нет ничего слишком сложного, скорее там много монотонной работы по кодированию. Однако приложения с использованием InterBase API являются при правильном написании наиболее производительными.

Поэтому изучайте примеры в этой книге- и создавайте on-line-игры, www-магазины и порталы!

Работа с InterBase с использованием ODBC

Интерфейсы ODBC основаны на международном стандарте ISO/EC 9075-3:1995 Information technology -- Database languages -- SQL -- Part 3: Call-Level Interface (SQL/CLI). Стандартизация интерфейсов доступа к данным позволяет разрабатывать "горизонтальные" приложения, не зависящие на уровне исходного кода от используемой базы данных.

Термин "ODBC" является сокращением английских слов "Open DataBase Connectivity" и обозначает набор интерфейсов прикладного уровня (API - Application Programming Interface), предоставляющих возможность обращения! к базам данных из приложений. Кроме интерфейсов, ODBC фирмы Microsoft? предоставляет инфраструктуру компонентов доступа к данным.

В этой главе описано использования драйвера Gemini InterBase ODBC для подключения приложений к базам данных InterBase с точки зрения пользователя, а также особенности данного драйвера. Если вы программируете с использованием интерфейса ODBC, вам следует ознакомиться документацию The ODBC Programmer's Reference, входящую в состав Microsoft Developer Network Library (MSDN).

Gemini InterBase ODBC driver соответствует версии 3.51 спецификации Microsoft ODBC, поддерживаются все функции уровней Level 0 (Core), Level 1 и большинство функций Level 2. Высокая степень соответствия стандарту позволяет использовать большинство приложений, поддерживающих интерфейс ODBC, среди которых:

* пакет Microsoft Office;

* генератор отчетов Seagate Crystal Reports;

* приложения, написанные с использованием технологии ADO, в том числе приложения ASP для Microsoft US;

* Microsoft SQL Server (использование баз данных InterBase как связанного сервера).

Драйвер существует в двух вариантах - настольном (desktop) и серверном (site). Первый вариант предназначен для офисных приложений, генераторов отчетов и других приложений, используемых на клиенте. Второй вариант рассчитан на использование в составе серверов приложений или Web-серверов.