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

Обработка исключений и ошибок подробно обсуждается в главе 32.

События

События Firebird являются "сигналами", которые модули PSQL могут накапливать в процессе выполнения для передачи клиентским приложениям, когда работа будет подтверждена. Клиентские приложения в сети могут прослушивать- с использованием обработчика сообщений- конкретные события, в которых они заинтересованы, без необходимости специального опроса наличия события.

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

Безопасность

Процедурам и триггерам могут быть предоставлены привилегии для специфических действий (SELECT, INSERT, DELETE и т.д.) к таблицам точно так же, как пользователям или ролям предоставляются привилегии. Не существует специального синтаксиса: используется обычный оператор GRANT, но в предложении то указывается триггер или процедура вместо пользователя или роли. Аналогичным образом привилегии процедур и триггеров могут отменяться оператором REVOKE.

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

Например, если пользователь выполняет UPDATE для таблицы А, что вызывает триггер, а триггер выполняет INSERT для таблицы в, то это действие будет допустимым, если пользователь имеет привилегии INSERT к этой таблице или триггер имеет привилегии INSERT к этой таблице.

Если у триггера или процедуры нет достаточных привилегий для выполнения их действий, Firebird вызывает ошибку SQL и устанавливает соответствующий код ошибки. Вы можете перехватить этот код ошибки в обработчике исключений точно так же, как и другие исключения. Информацию об операторах GRANT и REVOKE см. в главе 35.

Внутреннее устройство технологии

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

Запрос приходит от одного из следующих объектов:

* от клиентского приложения, которое напрямую выполняет хранимую процедуру;

* от триггера, который выполняет хранимую процедуру. Сюда относятся и системные триггеры, являющиеся частью систем поддержания ссылочной целостности или ограничений CHECK;

* от другой хранимой процедуры, которая выполняет эту хранимую процедуру.

Эффекты изменений

Однажды вызванный запрос к триггеру или хранимой процедуре сохраняется в кэше метаданных, пока существуют клиентские соединения с базой данных, независимо от того, использует ли какой-нибудь клиент этот триггер или хранимую процедуру. Не существует механизма убрать эти невыполняющиеся запросы из кэша метаданных. По этой причине изменения модулей PSQL являются "отложенными" в большей или меньшей степени в большинстве случаев. Возможность для клиентов видеть эти изменения отличается для Классического сервера и Суперсервера.

Суперсервер

Поскольку существующие запросы удаляются из кэша метаданных только тогда, когда последний клиент отключится от базы данных, они вообще никогда не будут обновлены в системах 24/7 (т. е. в системах, работающих 24 часа в сутки и 7 дней в неделю). Существует только один способ гарантировать, что все копии хранимых процедур и триггеров будут удалены из кэша метаданных - завершение всех соединений с базой данных. Когда пользователи снова соединятся с базой данных, они все увидят новые версии хранимых процедур и триггеров.

Классический сервер

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

Пора дальше

Теперь мы рассмотрим структуру модулей PSQL: что общего имеют триггеры и процедуры и чем они отличаются.

ГЛАВА 29. Разработка модулей PSQL.

Хранимые процедуры и триггеры объявляются при помощи операторов CREATE PROCEDURE и CREATE TRIGGER соответственно. Каждый из этих сложных операторов состоит из заголовка и тела.

Элементы процедур и триггеров

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

Хотя комплекс объявлений модуля PSQL является оператором DDL, расширения SQL в этом комплексе являются элементами структурированного языка высокого уровня, который имеет особые правила. Одним из этих правил, которое вы должны знать до начала работы, является использование терминатора оператора.

Оператор CREATE

Исходный код процедуры и триггера конструируется внутри "супероператора", который начинается с ключевых слов CREATE PROCEDURE или CREATE TRIGGER и завершается символом терминатора, следующим за конечным оператором END, например:

CREATE PROCEDURE ИМЯ . . .

. . .

AS

. . .

BEGIN

. . .

END ^

В хранимых процедурах и триггерах все операторы, следующие за ключевым словом AS, включают локальные переменные (если присутствуют) и логику программного модуля. Основное различие между триггерами и хранимыми процедурами заключается в заголовке оператора CREATE (СМ. рис. 29.1).

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

Каждый оператор внутри тела хранимой процедуры или триггера- кроме BEGIN и END- должен заканчиваться точкой с запятой. Никакой другой символ не является допустимым терминатором операторов в PSQL. В DSQL для операторов DML и DDL в Firebird точка с запятой также является терминатором по умолчанию. Она также является стандартом SQL для завершения операторов.

Такая ситуация может создать логическую проблему для синтаксического анализатора, который выполняет предварительную компиляцию наших модулей PSQL: какая точка с запятой завершает операторы внутри модуля, а какая завершает определение CREATE?

Чтобы обойти эту проблему, в Firebird есть синтаксис переключения SET TERM, который позволяет вам устанавливать другой внешний терминатор, который воздействует на внешние операторы, в то время как синтаксический анализатор обрабатывает определения PSQL. В скриптах опытные разработчики часто используют одиночный оператор SET TERM в начале каждого скрипта, чтобы использовать свой любимый альтернативный терминатор в течение всего времени выполнения скрипта. Некоторые инструменты администратора баз данных поддерживают средства конфигурирования альтернативных терминаторов в своих редакторах и программах выделения метаданных.

Операторы SET TERM используются в isql и в скриптах.

Утилита isql предварительно анализирует каждый оператор и отправляет любой завершенный терминатором оператор на сервер в виде одной команды, SET TERM является одним из собственных операторов ISQL, который используется не для пересылки запроса на сервер, а для подготовки собственного синтаксического анализатора для различной интерпретации терминаторов. (Другие операторы SET В ISQL также вызывают специальные действия в программе isql, которые не имеют значения вне isql.)

DSQL совсем не распознает терминаторы операторов. Большинство других утилит, выполняющих скрипты, отправляют операторы DDL на сервер один за другим без терминаторов. Они выполняют свой собственный синтаксический анализ для распознавания начала и завершения операторов CREATE PROCEDURE и передают внутренние терминаторы точка с запятой просто как обычные символы синтаксиса составного оператора.