Заметки о системных таблицах InterBase

         

Триггеры.


Триггер - это процедура базы данных, которая автоматически вызывается SQL сервером при возникновении определенных событий (добавление, удаление, обновление записей).

Попробуем узнать, какие триггеры есть в базе данных. Информация о триггерах содержится в служебной таблице RDB$TRIGGERS.

select RDB$TRIGGER_NAME from RDB$TRIGGERS where (RDB$SYSTEM_FLAG = 0) or (RDB$SYSTEM_FLAG is NULL);

Условие этого SQL-запроса позволяет выбрать только триггеры, созданные пользователем. Однако нужно отметить, что в результате запроса будут и триггеры, обеспечивающие ограничения CHECK. Эти триггеры создаются не явно, когда Вы описываете ограничение. Как же получить список триггеров, действительно созданных пользователем. Все триггеры, обеспечивающие CHECK ограничения, перечислены в таблице RDB$CHECK_CONSTRAINTS. Поэтому следующим запросом мы можем их отсечь.

select RDB$TRIGGER_NAME from RDB$TRIGGERS where ((RDB$SYSTEM_FLAG = 0) or (RDB$SYSTEM_FLAG is NULL)) and (RDB$TRIGGER_NAME not in (select RDB$TRIGGER_NAME from RDB$CHECK_CONSTRAINTS));

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

В той же таблице RDB$TRIGGERS находятся и другие параметры триггера. Попробуем извлечь их.

select RDB$TRIGGER_NAME, RDB$RELATION_NAME, RDB$TRIGGER_SEQUENCE, RDB$TRIGGER_TYPE, RDB$TRIGGER_SOURCE, RDB$TRIGGER_INACTIVE from RDB$TRIGGERS where ((RDB$SYSTEM_FLAG = 0) or (RDB$SYSTEM_FLAG is NULL)) and (RDB$TRIGGER_NAME not in (select RDB$TRIGGER_NAME from RDB$CHECK_CONSTRAINTS));

В результате мы получим не просто список триггеров, а узнаем, какой таблице триггер принадлежит (RDB$RELATION_NAME), порядковый номер триггера (RDB$TRIGGER_SEQUENCE), определяющий, в какой последовательности триггеры будут выполнятся, если они одного типа и принадлежат одной таблице, тип триггера (RDB$TRIGGER_TYPE), исходный код триггера (RDB$TRIGGER_SOURCE). Кроме того, мы узнаем состояние триггера, активен ли он в данный момент (RDB$TRIGGER_INACTIVE). Значение этого поля, установленное в 0, говорит о том, что триггер активен. Скажем еще пару слов о типе триггера. Поле RDB$TRIGGER_TYPE имеет тип короткого целого, и в нем числами зашифрован тип триггера. Посмотрим, можно ли представить эти значения более читабельными. Различная информация о подобных зашифрованных типах содержится в таблице RDB$TYPES.


select a.RDB$TRIGGER_NAME, a.RDB$RELATION_NAME, a.RDB$TRIGGER_SEQUENCE, b.RDB$TYPE_NAME, a.RDB$TRIGGER_SOURCE, a.RDB$TRIGGER_INACTIVE from RDB$TRIGGERS a, RDB$TYPES b where (a.RDB$TRIGGER_TYPE=b.RDB$TYPE) and (b.RDB$FIELD_NAME="RDB$TRIGGER_TYPE") and ((a.RDB$SYSTEM_FLAG = 0) or (a.RDB$SYSTEM_FLAG is NULL)) and (a.RDB$TRIGGER_NAME not in (select RDB$TRIGGER_NAME from RDB$CHECK_CONSTRAINTS));

Поле b.RDB$ TYPE_NAME будет содержать расшифровку типа триггера, хотя она и отличается от той, к которой мы привыкли. На всякий случай приведу таблицу сооветствия значений типов, взятых из разных источников.
Код Значение из документации Значение из таблицы RDB$TYPES
1 BEFORE INSERT PRE_STORE
2 AFTER INSERT POST_STORE
3 BEFORE UPDATE PRE_MODIFY
4 AFTER UPDATE POST_MODIFY
5 BEFORE DELETE PRE_ERASE
6 AFTER DELETE POST_ERASE
Триггеры - это очень хорошо. Но бывают ситуации, когда нужно приостановить их работу. Например: нужно перенести данные из базы данных формата dbf, где ссылки между таблицами определяются значениями в некоторых полях. Самое простое - это перенести все значения как они есть, чтоб не нарушать ссылочную целостность, но, если в базе данных InterBase существуют триггеры, генерирующие уникальные значения, то возможет конфликт или нарушение ссылок. Сам попадался на этом. По этому было бы не плохо временно остановить работу триггеров. Попробуем получить скрипт для выполнения подобной операции.

SELECT "ALTER TRIGGER " RDB$TRIGGER_NAME "INACTIVE;" FROM RDB$TRIGGERS WHERE ((RDB$SYSTEM_FLAG = 0) OR (RDB$SYSTEM_FLAG IS NULL)) AND (RDB$TRIGGER_NAME NOT IN (SELECT RDB$TRIGGER_NAME FROM RDB$CHECK_CONSTRAINTS));

Если выполнить этот SQL-запрос в Windows ISQL, то из области результата можно скопировать готовый скрипт. Учтите, что в него попадут, не только триггеры, гинерирующие уникальные значения полей, но и другие, активность которых вполне можкт быть уместной. Поэтому рекомендую, получившийся скрипт скорректировать.


Содержание раздела