Изменение триггеров

We use cookies. Read the Privacy and Cookie Policy

Изменение триггеров

Firebird 1.0.x предоставляет только один способ изменения триггеров при использовании операторов DDL, a Firebird 1.5 добавляет еще один.

* ALTER TRIGGER изменяет определение существующего модуля триггера, сохраняя его зависимости от других объектов. Он может быть использован с минимальным беспокойством по поводу деактивации триггера.

* CREATE OR ALTER TRIGGER (версия 1.5 и выше) создает модуль триггера, если он не существует, и работает точно так же, как и CREATE TRIGGER. В противном случае применяются правила ALTER, и зависимости сохраняются.

Любая операция завершится с исключением при любой попытке изменений, которая отменяет зависимости.

Синтаксис для изменения триггеров

Синтаксис:

{ALTER TRIGGER ИМЯ} |

{CREATE OR ALTER TRIGGER имя FOR {таблица | просмотр}

[ACTIVE | INACTIVE]

[{BEFORE | AFTER} {DELETE | INSERT | UPDATE}]

[POSITION число]

AS <тело-триггера>;

ALTER TRIGGER

Предложение FOR ИМЯ, применяемое в CREATE TRIGGER, опускается, ALTER TRIGGER не может использоваться для изменения таблицы, с которой ассоциирован триггер.

Изменение только заголовка

Когда вы используете ALTER TRIGGER для изменения только заголовка, оператор требует по меньшей мере одного изменяемого атрибута после имени триггера. Любой атрибут заголовка, опущенный в этом операторе, остается неизменным.

Следующий оператор деактивирует триггер SAVE_SALARY_CHANGE:

ALTER TRIGGER SAVE SALARY CHANGE INACTIVE;

Если изменяется индикатор фазы (BEFORE или AFTER), ТО событие (UPDATE, INSERT или DELETE) также должно быть указано. Например, следующий оператор заново активирует триггер SAVE_SALARY_CHANGE и указывает, что он будет выполняться до изменения, а не после:

ALTER TRIGGER SAVE_SALARY_CHANGE

ACTIVE BEFORE UPDATE;

Изменение тела

Любое изменение тела триггера приводит к тому, что новое определение тела заменяет старое определение. Оператор ALTER TRIGGER не должен содержать никакую информацию заголовка, кроме имени триггера.

Например, следующий оператор изменяет триггер SET CUST NO, который был создан с таким определением:

CREATE TRIGGER SET_CUST_NO FOR CUSTOMER

BEFORE INSERT

AS

BEGIN

IF (NEW.CUST_NO IS NULL) THEN

NEW.CUST_NO = GEN_ID(CUST_NO_GEN, 1);

END^

Мы изменим этот триггер, чтобы он добавлял новую строку в таблицу NEW CUSTOMERS каждый раз, когда новая строка добавляется в таблицу CUSTOMER:

SET TERM ^;

ALTER TRIGGER SET_CUST_NO

BEFORE INSERT AS

BEGIN

IF (NEW.CUST_NO IS NULL) THEN

NEW.CUST_NO = GEN_ID(CUST_NO_GEN, 1);

INSERT INTO NEW_CUSTOMERS(NEW.CUST_NO, CURRENT_DATE) END ^

SET TERM ;^

CREATE OR ALTER TRIGGER

В версии 1.5 этот новый синтаксис создает триггер, если триггер с указанным именем не найден, или изменяет триггер с этим именем. Просто отредактируйте исходный оператор CREATE нужным образом, добавив ключевые слова OR ALTER.

Ошибка "объект находится в использовании"

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

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

Inactive/Active

В версии 1.5 и более поздних выполнение ALTER TRIGGER ... INACTIVE | ACTIVE обычно не приводит к ошибке "объект находится в использовании", если только существующая транзакция не заблокировала таблицу. Такое изменение не влияет на транзакции, которые уже используют эту таблицу. Причем данное изменение будет видимым следующей транзакции, которая запрашивает изменение состояния таблицы.