Вход/Регистрация
Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
вернуться

Борри Хелен

Шрифт:

* Триггер BEFORE UPDATE для инициатора запроса потребуется для обработки сложного правила, такого как описано в предыдущем пункте для проверки дат и, возможно, других критериев для осуществления правила и выбора корректного ключа.

Реализация пользовательской ссылочной целостности

Предположим, мы имеем следующие две таблицы:

CREATE TABLE LOOKUP (

UQ_ID SMALLINT NOT NULL UNIQUE,

VALUE1 VARCHAR(30) NOT NULL,

VALUE2 CHAR(2) NOT NULL,

START_DATE DATE,

END_DATE DATE) ;

COMMIT;

/* */

CREATE TABLE REQUESTOR (

ID INTEGER NOT NULL PRIMARY KEY,

LOOKUP_ID SMALLINT,

DATA VARCHAR(20)

TRANSAC_DATE TIMESTAMP NOT NULL) ;

COMMIT;

Теперь мы перейдем к установлению правил существования для двух таблиц. Мы планируем использовать исключения для остановки событий DML, которые нарушают целостность. Следовательно, вначале мы создадим эти исключения:

CREATE EXCEPTION NO_DELETE

'Can not delete row required by another table';

/* Нельзя удалять строку, нужную другой таблице */

CREATE EXCEPTION NOT_VALID_LOOKUP

'Not a valid lookup key';

/* Неверный ключ соответствия */

CREATE EXCEPTION NO_AUTHORITY

'You are not authorized to change this data';

/* Вы не можете изменять эти данные */

COMMIT;

Первый триггер выполняет проверку существования при попытке удалить строку соответствия:

SET TERM ^;

CREATE TRIGGER BD_LOOKUP FOR LOOKUP

ACTIVE BEFORE DELETE

AS

BEGIN

IF (EXISTS(

SELECT LOOKUP_ID FROM REQUESTOR

WHERE LOOKUP_ID = OLD.UQ_ID)) THEN

EXCEPTION NO_DELETE;

END ^

Другая сторона проверки существования: ключ соответствия не может быть назначен, если он отсутствует в таблице соответствия:

CREATE TRIGGER BA_REQUESTOR FOR REQUESTOR

ACTIVE BEFORE INSERT OR UPDATE

AS

BEGIN

IF (NEW.LOOKUP_ID IS NOT NULL

AND NOT EXISTS (

SELECT UQ_ID FROM LOOKUP

WHERE UQ_ID = NEW.LOOKUP_ID)) THEN

EXCEPTION NOT_VALID_LOOKUP;

END ^

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

CREATE TRIGGER BA_LOOKUP FOR LOOKUP

ACTIVE BEFORE UPDATE OR DELETE

AS

BEGIN

IF (CURRENT_USER <> 'CHIEFACCT') THEN

EXCEPTION NO_AUTHORITY;

END ^

Этот триггер будет проверять входной код соответствия, чтобы убедиться, что он правилен для периода транзакции, и будет корректировать его при необходимости:

CREATE TRIGGER BA_REQUESTORl FOR REQUESTOR

ACTIVE BEFORE INSERT OR UPDATE POSITION 1

AS

DECLARE VARIABLE LOOKUP_NUM SMALLINT;

DECLARE VARIABLE NEED_CHECK SMALLINT = 0;

BEGIN

IF (INSERTING AND NEW.LOOKUP_ID IS NOT NULL) THEN

NEED_CHECK = 1;

IF (UPDATING) THEN

IF (

(OLD.LOOKUP_ID IS NULL

AND NEW.LOOKUP_ID IS NOT NULL)

OR (OLD.LOOKUP_ID IS NOT NULL

AND NEW.LOOKUP_ID <> OLD.LOOKUP_ID)) THEN

NEED_CHECK = 1;

IF (NEED_CHECK = 1) THEN

BEGIN

SELECT L1.UQ_ID FROM LOOKUP L1

WHERE L1.START_DATE <= CAST(NEW.TRANSAC_DATE AS DATE)

AND L1.END_DATE >= CAST(NEW.TRANSAC_DATE AS DATE)

AND L1.VALUE2 = (SELECT L2.VALUE2 FROM LOOKUP L2

WHERE L2.UQ_ID = NEW.LOOKUP_ID)

INTO :LOOKUP_NUM;

NEW.LOOKUP_ID = LOOKUP_NUM;

END

END ^

COMMIT ^

SET TERM ;^

Изменение строк в той же таблице

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

  • Читать дальше
  • 1
  • ...
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: