C.12.2.6. Корреляционные имена

Для триггера, который возбуждается только для удаления есть только значение ячейки old.

  DELETE INSERT UPDATE
BEFORE :Old :New :Old,:New
AFTER :Old :New :Old

Триггер возбуждается по событию, до события - old, после - new. Во время использования триггер может обратиться как к старым так и новым значениям

: old корреляционные имена

: new

активирующий оператор :old : new
INSERT не определенно значение null значение, которое вводится после выполнения оператора
UPDATE исходное значение содержащиеся перед обновление данных новое значение, которое будет введено после выполнения оператора
DELETE определенно, исходное значение, содержащееся в строке перед ее удалением не определена везде null

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

INSERTING - TRUE если активирован оператор INSERT, FALSE - в противном случае;

DELETING - TRUE если активирован оператор DELETE, FALSE - в противном случае;

UPDATING - TRUE если активирован оператор UPDATE, FALSE - в противном случае;

Пример

Drop table USP;

Drop table predmet;

Drop table teachers;

Drop table students;

Drop table students1;

Create table students(snum number not null;

Sfam varchar 2(10);

Stip number;

premory key (snum));

Create table students1(snum number not null;

Sfam varchar 2(10);

Stip number;

Tip varchar 2(10));

Create table teachers (tnum number not null;

tfam varchar 2(10);

premory key (tnum));

Create table predmet (pnum number not null;

Pname varchar 2(10);

Sfam varchar 2(10);

Hours number;

Couts number;

premory key (pnum);

foreign key (tnum) references teachers);

Create table USP (unum number not null;

Ocenka number;

snum number not null;

unum number not null;

premory key (unum)

foreign key (snum) references student;

foreign key (pnum) references predmet);

Drop table TRG;

Create trigger TRG

Before insert or delete or update student

For each row

Declare

Rw1 number;

Rw2 varchar 2(10);

Rw3 number;

Rw4 varchar 2(10);

Begin

If updating then

Begin

Rw1=:old.snum;

Rw2 =: old.sfam;

Rw3=:old.stip;

Rw4:= ▒update▓;

Insert into students1 Values (rw1,rw2,rw3,rw4);

End;

Elsif deleting then

Begin

Rw1:=:old.snum;

Rw2:=:old.sfam;

Rw3:=:old.stip;

Rw4:= ▒delete▓;

Insert into students1 Values (rw1,rw2,rw3,rw4);

End;

Elsif inserting then

Begin

Rw1:=:new.snum;

Rw2:=:new.sfam;

Rw3:=:new.stip;

Rw4:= ▒insert▓;

Insert into students1 Values (rw1,rw2,rw3,rw4);

End;

Endif;

End;

[заполнение таблиц]

[изменение таблиц]

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

СЛУЖАЩИЕ (НОМЕР_ПРОПУСКА, ФИО, НОМЕР_ОТДЕЛА, ЗАРПЛАТА)

ОТДЕЛЫ (НОМЕР_ОТДЕЛА, НОМЕР_ПРОПУСКА_НАЧАЛЬНИКА, ЧИСЛО_СЛУЖАЩИХ,

ФОНД_ЗАРПЛАТЫ)

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

SELECT ЧИСЛО_СЛУЖАЩИХ FROM ОТДЕЛЫ =

SELECT COUNT (*) FROM СЛУЖАЩИЕ

WHERE НОМЕР_ОТДЕЛА = ОТДЕЛЫ.НОМЕР_ОТДЕЛА

SELECT ФОНД_ЗАРПЛАТЫ FROM ОТДЕЛЫ <=

SELECT SUM (ЗАРПЛАТА) FROM СЛУЖАЩИЕ

WHERE НОМЕР_ОТДЕЛА = ОТДЕЛЫ.НОМЕР_ОТДЕЛА

Предположим, что в отделе кадров работает всего два человека: начальник отдела кадров, который, естественно, имеет доступ к обеим таблицам и, в частности, является ответственным за выполнение операций смены начальника отдела или изменения фонда заработной платы. Второй человек - рядовой клерк, который по указанию начальника выполняет рутинную работу оформления новых сотрудников или увольнения ранее работавших. Естественно, что для выполнения его операций достаточно иметь доступ только к таблице СОТРУДНИКИ. Но тогда при выполнении любой из двух операций он просто не может не нарушить по крайней мере первое из упомянутых выше ограничений целостности. Конечно, можно внести соответствующие корректирующие действия в код прикладной программы, соответствующей операциям клерка, но тогда он неявно получит доступ по изменению ответственной таблицы ОТДЕЛЫ. Поэтому лучше определить триггеры вида

ON INSERT TO СЛУЖАЩИЕ

UPDATE ОТДЕЛЫ SET NEW (ЧИСЛО_СЛУЖАЩИХ) = OLD (ЧИСЛО_СЛУЖАЩИХ) + 1

WHERE НОМЕР_ОТДЕЛА = СЛУЖАЩИЕ.НОМЕР_ОТДЕЛА

ON DELETE FROM СЛУЖАЩИЕ

UPDATE ОТДЕЛЫ SET NEW (ЧИСЛО_СЛУЖАЩИХ) = OLD (ЧИСЛО_СЛУЖАЩИХ) - 1

WHERE НОМЕР_ОТДЕЛА = СЛУЖАЩИЕ.НОМЕР_ОТДЕЛА

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

Вторая область применения триггеров - автоматический мониторинг действий конечных пользователей. Снова приведем очень простой пример. Начальник отдела кадров хочет знать, сколько операций в день выполняет его клерк. Тогда он должен сказать об этом на стадии анализа требований, и в результате, например, будет создана таблица

СТАТИСТИКА (ТЕКУЩАЯ_ДАТА, ЧИСЛО_ОПЕРАЦИЙ)

и триггер вида

ON INSERT, DELETE FROM СЛУЖАЩИЕ

IF EXISTS (SELECT * FROM СТАТИСТИКА WHERE ТЕКУЩАЯ_ДАТА = TODAY)

UPDATE СТАТИСТИКА SET

NEW (ЧИСЛО_ОПЕРАЦИЙ) = OLD (ЧИСЛО_ОПЕРАЦИЙ) + 1

WHERE ТЕКУЩАЯ_ДАТА = TODAY

ELSE

INSERT INTO СТАТИСТИКА (TODAY, 1)

Два замечания. Во-первых, в распространенном на сегодня стандарте SQL/92 механизм триггеров не специфицирован. В СУБД, которые поддерживают этот механизм, соответствующие языковые средства и их семантика различаются. Поэтому на текущий момент использование механизма триггеров неявно влечет сильную привязку к конкретному производителю. Во-вторых, как и в случае определения представлений и ограничений целостности, при определении триггеров необходимо учитывать распределенный характер базы данных и возможности сервера ссылаться на "чужие" таблицы.

Наконец, в базе данных могут находитьсяхранимые процедуры. Интересно, что в стандарте SQL/92 вообще не встречается термин "хранимая процедура". В стандарте специфицированы два способа взаимодействия прикладной программы с сервером баз данных.

1.Первый, наиболее часто используемый способ состоит во встраивании операторов языка SQL в программу, написанную на одном из традиционных языков программирования. В самом стандарте определены правила встраивания SQL в программы, которые написаны на языках Си, Паскаль, Фортран, Ада и т. д.

2. Второй способ основан на специфицированном в стандарте "языке модулей SQL". С использованием этого языка можно определить модуль, содержащий несколько процедур, каждая из которых соответствует некоторому параметризованному оператору SQL. В прикладной программе содержатся не операторы SQL, а лишь вызовы процедур (с указанием фактических параметров) из модуля SQL, с которым эта прикладная программа связана (правила связывания в стандарте не определены). Заметим, что стандарт не обязывает следовать каким-то конкретным правилам при реализации встроенного SQL или языка модулей.

Идея же процедур SQL, определяемых на языке модулей, повлекла внедрение во многие реализации механизма хранимых процедур. Хранимая процедура - это именованная, параметризованная конструкция, определяемая на языке SQL или некотором его расширении, встраиваемая в прикладную программу, компилируемая на стороне сервера во время обработки текста процедуры прекомпилятором. Выполняемый или интерпретируемый код хранимой процедуры сохраняется в базе данных, а сама она может быть вызвана из любой прикладной программы авторизованного пользователя (того, кто получил привилегию на выполнение этой процедуры) с указанием фактических параметров.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: