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

Никогда не используется

Переходит на финальный END

Передает управление следующему триггеру той же фазы (BEFORE или AFTER), что и у текущего, если тот существует. Иначе завершает работу триггеров этой фазы

LEAVE

В Firebird 1.5 появился оператор LEAVE для выхода из блоков. Он заменил оператор BREAK, который был частично реализован в версии 1.0.x. Вот пример его использования в цикле WHILE нашей процедуры IS_PORK_SAFE:

WHILE (SI < 9) DO

BEGIN

SI = SI + 1; /* арифметическое выражение */

IF (SUBSTRING(SMONTH FROM 1 FOR 1) = 'R') THEN

BEGIN

RESPONSE = 'YES'; /* простая константа */

LEAVE;

END

SMONTH = SUBSTRING(SMONTH FROM 2);

/* функциональное выражение */

END

LEAVE приводит к выходу из цикла - в нашем случае останавливается проверка букв слова на символ "R". Если ветвь, содержащая оператор LEAVE, не выполняется, то выполнение продолжается до конца цикла.

EXCEPTION

Оператор EXCEPTION останавливает выполнение и передает управление первому блоку обработки исключений (блоку, начинающемуся с ключевого слова WHEN), который может обработать исключение. Если для этого исключения не найден обработчик, управление передается финальному оператору END и процедура завершается аварийно. Когда происходит такое, один или более кодов исключения передается назад клиенту через вектор состояния ошибок (массив).

Оператор EXCEPTION используется в блоке IF ... THEN ... ELSE для вызова пользовательских исключений, предварительно определенных как объекты базы данных. Сервер Firebird вызывает свои собственные исключения для SQL и контекста ошибок. Поток управления в этих случаях точно такой же, как и при вызове пользовательских исключений.

Синтаксис и техники вызова и обработки исключений описаны в главе 32.

EXECUTE STATEMENT

Firebird 1.5 вводит расширение PSQL, поддерживающее выполняемые строки. Приложение или процедура могут передать оператор DSQL (DDL или DML) в виде строки входного аргумента (либо процедура может сконструировать эту строку как локальную переменную) для выполнения с использованием EXECUTE STATEMENT.

EXECUTE STATEMENT добавляет гибкости хранимым процедурам и триггерам, но с высоким риском ошибок. Возвращаемые значения жестко проверяются на типы данных, чтобы избежать непредсказуемых исключений преобразования данных. Например, строка '1234' может быть преобразована в целое, a 'abc' вызовет ошибку преобразования. Во время компиляции такая строка не может быть проанализирована и проверена.

Синтаксис:

[FOR] EXECUTE STATEMENT <строка>

[INTO :переменная1 [, :переменная2 [, :переменнаяN ] ] DO

<составной-оператор>];

<составной-оператор> = {оператор \ блок-операторов}

Конструирование выражения или строковой переменной для создания оператора DSQL в строке аргумента должно быть завершено к моменту выполнения EXECUTE STATEMENT. Выполняемый оператор DSQL в строке аргумента не может содержать никаких заменяемых параметров.

В своей простейшей форме EXECUTE STATEMENT выполняет оператор SQL, запрашивающий операцию, которая не возвращает строк данных, а именно:

* INSERT, UPDATE, DELETE;

* EXECUTE PROCEDURE;

* любой оператор DDL за исключением CREATE/DROP DATABASE. Например:

CREATE PROCEDURE EXEC_PROC (PROC_NAME VARCHAR (31))

AS

DECLARE VARIABLE SQL VARCHAR(1024);

DECLARE VARIABLE . . .

BEGIN

. . .

SQL = 'EXECUTE PROCEDURE ' || PROC_NAME;

EXECUTE STATEMENT SQL;

END ^

Процедура вызывает следующее:

EXECUTE PROCEDURE EXEC_PROC ( ' PROJECT_MEMBERS ' ) ;

Переменные значения в одиночном SELECT

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

CREATE PROCEDURE SOME_PROC

(TABLE_NAME VARCHAR (31), COL_NAME VARCHAR (31))

AS

DECLARE VARIABLE PARAM DATE;

BEGIN

EXECUTE STATEMENT 'SELECT MAX ( ' || COL_NAME || ') FROM ' || TABLE_NAME

INTO : PARAM;

. . .

FOR SELECT . . . . FROM . . . .

WHERE END_DATE = : PARAM

INTO ... DO

. . .

END ^

Переменные значения в многострочном SELECT

Синтаксис EXECUTE STATEMENT также поддерживает выполнение оператора SELECT внутри цикла FOR для возвращения по одной строки за раз в список переменных. Не существует ограничений на используемый оператор SELECT, однако помните, что во время компиляции синтаксический анализатор не может проверить содержимое строки.

CREATE PROCEDURE DYNAMIC_SAMPLE (

TEXT_COL VARCHAR(31),

TABLE_NAME VARCHAR (31))

RETURNS (LINE VARCHAR(32000))

AS

DECLARE VARIABLE ONE_LINE VARCHAR (100);

DECLARE VARIABLE STOP_ME SMALLINT;

BEGIN

LINE = ' ' ;

STOP_ME = 1;

FOR EXECUTE STATEMENT

'SELECT ' || TEXTCOL || ' FROM ' || TABLE_NAME

INTO :ONE_LINE DO

BEGIN

IF (STOP_ME > 320) THEN

EXIT;

IF (ONE_LINE IS NOT NULL) THEN

LINE = LINE || ONE_LINE || ' '

STOP_ME = STOP_ME + 1;

END

SUSPEND;

END ^

Предостережения

Средство EXECUTE STATEMENT предназначено только для очень осторожного использования и должно применяться с учетом всех факторов. Используемые в нем операции медленны и рискованны. Возьмите за правило применять его только в случае невозможности получить нужные результаты другими средствами или (что маловероятно) когда это действительно улучшает выполнение оператора. Будьте в курсе, что есть риск:

* не существует способа проверить синтаксис оператора в строке аргумента;

* не проверяются зависимости или существование защиты для предотвращения удаления или изменения таблиц или столбцов;

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

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

POST_EVENT

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

Синтаксис оператора:

POST_EVENT имя-события;

Это приводит к тому, что событие имя-события "отправляется" в стек, имя-события может быть любой строкой, содержащей до 78 символов и не требующей предварительного определения на сервере. Помещенные в стек события будут отправлены клиентам, "прослушивающим" события с помощью обработчика извещений (event alerter).

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

Подробности см. в разд. "События" главы 32.

Разработка модулей

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