Указание момента инициирования триггера 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Указание момента инициирования триггера



 

При определении триггера предоставляется возможность указать момент ини­циирования выполнения его тела, а именно — должен ли триггер быть иницииро­ван перед выполнением предложения-события (триггер предобработки) или по­сле (триггер постобработки). Для этого в SQL используются фразы BEFORE или AFTER. Эти оба вида триггеров применяются как в триггерах над строками, так и в триггерах над предложением (см. далее).

Триггеры предобработки (или, как их еще называют, бифор-триггеры) иниции­руются до того, как будет выполнено их предложение-событие. Триггеры этого типа обычно используются в двух случаях.

- Действие триггера должно определить, является ли допустимым использова­ние предложения-события в текущем контексте. Использование в этом случае триггера предобработки позволяет аннулировать нежелательное выполнение предложения-события.

- До выполнения предложений-событий INSERT или UPDATE следует получить специфические значения тех или иных столбцов.

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

Допустим, имеется таблица, в которой будут регистрироваться некоторые дейст­вия, выполняемые над таблицей FACULTY:

CREATE TABLE FacultyLog (LogDate DATE, Action VARCHARC255)):

Определим триггер, который после завершения выполнения обновления фонда в таблице FACULTY записывает в журнал регистрации изменений FacultyLog соот­ветствующую строку:

 

CREATE TRIGGER LogFacFundUpdate AFTER UPDATE OF Fund ON FACULTY BEGIN

INSERT INTO FacultyLog (LogDate. Action)

VALUES (SYSDATE. 'Фонд обновлен');

END;

 

Теперь, если мы выполним обновление фонда любого из факультетов:

 

UPDATE FACULTY SET Fund = 30000 WHERE FacPK - 1;

то в файле журнала появится соответствующая строка:

SELECT T0_CHAR(LogDate. 'DD-MM-YYYY HH:MI:SS’) "Дата".

Action "Действие”

FROM FacultyLog;

Дата                Действие

---------------------------------------------------

12-01-2006 08:58:20 Фонд обновлен

 

Событие триггера

 

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

 

INSERT | DELETE | {UPDATE [OF список_столбцов]}

 

Как видите, с триггером может быть связано только одно событие. Если предло­жением-событием является UPDATE, можно добавить факультативный список столб­цов. Если они указаны, триггер инициируется при их обновлении. Если список столбцов отсутствует, триггер инициируется при обновлении любого столбца. В за­висимости от вида события говорят о триггерах вставки, удаления и обновления.

 

Объект триггера

 

Объект триггера специфицируется фразой:

 

ON имя_таблицы

 

Как видим, в стандарте SQL в качестве объекта триггера может выступать только таблица базы данных, причем только одна.

 

Ссылочные имена триггера

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

Стандарт SQL предполагает существование специальных переменных, которые позволяют ссылаться на таблицы переходов в теле триггера. Для триггеров на уровне предложения (об уровнях триггера см. далее) значением соответствую­щей переменной является вся таблица перехода. Для триггеров на уровне строки переменная принимает значение соответствующей строки таблицы переходов и называется переменной перехода. Когда при обновлении на уровне строк базовой таблицы создаются две таблицы переходов (старая и новая), переменные этих таблиц переходов попарно синхронизированы. То есть одна из них указывает на строку до обновления, а другая — на ту же строку после обновления. Для указа- ния имен этих четырех переменных используется приводимая ниже конструкция:

 

REFERENCING{OLD[ROW][AS]имя_старой_переменной_перехода

| NEW [ROW] [AS] имя_новой_переменной_перехода

|OLD TABLE [AS] имя_старой_таблицы_перехода

| NEW TABLE [AS] имя_новой_таблицы_перехода}...

 

Каждый из четырех вариантов может присутствовать в списке только один раз. В связи с ограничениями на существование старых (новых) таблиц и переменных переходов в зависимости от вида события допускаются не все варианты опреде­ления ссылочных имен — они представлены в таблице 2.

 

 

Таблица 2 - Допустимые варианты определения ссылочных имен

 

Событие Вариант
INSERT NEW ROW, NEW TABLE
DELETE OLD ROW, OLD TABLE
UPDATE любой

 

Кроме того, если определяется триггер на уровне строки (см. далее), можно ука­зать имена только для вариантов NEW ROW и OLD ROW.

 

Уровень триггера

 

Уровень триггера определяется синтаксически одной из следующих форм:

 

FOR EACH {ROW | STATEMENT}

 

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

- По одному разу относительно каждой строки, которая будет подвергнута воз­действию предложением-событием триггера (фраза FOR EACH ROW). В этом слу­чае говорят, что это триггер уровня строки (или триггер над строками);

- Один раз относительно предложения-события независимо от того, сколько строк оно обрабатывает (фраза FOR EACH STATEMENT). В этом случае говорят, что это триггер уровня предложения (или триггер над предложением).

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

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

 

CREATE TABLE TeacherLog (

TchID INTEGER.

LogDate DATE.

OldSalary NUMBERC6. 2).

Newsalary NUMBERC6. 2)):

 

В ней мы будем сохранять идентификатор преподавателя, дату изменения став­ки, значение ставки до обновления и после. Теперь создадим триггер:

 

CREATE TRIGGER LogSalUpdate AFTER

UPDATE OF Salary ON TEACHER

FOR EACH ROW

BEGIN

INSERT INTO TeacherLog (TchID. LogDate. OldSalary. NewSalary)

VALUES (:NEW.TchPK. SYSDATE,:0LD.Salary.:NEW.Salary);

END;

 

Триггер создан.

Здесь:NEW и:0LD являются ссылочными именами на новые и старые переменные перехода в синтаксисе Oracle. Теперь увеличим на 10% ставку доцентов и по­смотрим, что будет зафиксировано в таблице TeacherLog.

 

UPDATE TEACHER SET Salary = Salary * 1.10

WHERE LOWER(Post) = 'доцент1:

4 строк обновлено.

SELECT * FROM TeacherLog:

 

TCHID LOGDATE OLDSALARY NEWSALARY

----------------------------------------------------------------------------

                                  4 12.01.2006       830 913

                                                   6 12.01.2006    770 847

                                                   7 12.01.2006    890 979

                                                 14 12.01.2006    770 847

 

Как видим, по одному предложению обновления в журнале регистрации сформи­ровано четыре строки, так как наш триггер является триггером на уровне строк.

Триггер на уровне предложения обрабатывается только один раз относительно предложения-события независимо от того, сколько строк подвергаются воздейст­вию этого предложением (даже если ни одна строка не будет обработана!). На­пример, если предложение-событие предполагает удаление многих строк, его триггер, описанный на уровне предложения, будет отработан только один раз, даже когда предложение-событие не удалит ни одной строки.

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

 

Условие триггера

 

Условие триггера определяет логическое выражение, истинность которого разре­шает выполнить тело триггера. Если условие принимает значения FALSE или UNKNOWN, триггер не выполняется. Синтаксис условия следующий:

WHEN (условие)

где условие — любое допустимое в SQL условное выражение. Ограничение тригге­ра задается только в триггерах над строками. При его наличии условие проверя­ется на каждой строке, которая должна инициировать триггер. Если выражение оказывается истинным запускается на выполнение тело триггера. Если же выра­жение принимает значение FALSE или UNKNOWN тело триггера не выполняется для такой строки. Приведем пример условного триггера.

 

CREATE TRIGGER DepFundChanged AFTER

UPDATE ON DEPARTMENT

FOR EACH ROW

WHEN (NEW.Fund <> OLD.Fund)

BEGIN

UPDATE FACULTY

SET FACULTY.Fund = (SELECT SUM(Fund) + 10000 FROM DEPARTMENT

WHERE DEPARTMENT.FacFK =‘:NEW.FacFK)

WHERE FACULTY.FacPK =:NEW.FacFK;

END:

 

Это триггер постобработки, который инициируется командой обновления таблицы DEPARTMENT. Условием выполнения триггера является изменение значения фонда финансирования кафедры. В этом случае тело триггера подсчитывает новое зна­чение фонда финансирования факультета, которому принадлежит кафедра. То есть в данном случае предполагается, что фонд факультета должен автоматиче­ски подсчитываться равным сумме фондов всех его кафедр плюс 10 000.

 

Действие триггера

 

Согласно стандарту SQL действие триггера представляет собой либо отдельное допустимое предложение SQL, либо совокупность таких предложений, задавае­мых в соответствии с таким синтаксисом:

 

BEGIN

{5(Х_предложение:}...

END

 

Таким образом, стандарт предполагает, что тело триггера может состоять из сово­купности предложений SQL.

 

Удаление триггера

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

DROP TRIGGER имя триггера

 

Переопределение триггера в стандарте SQL не предусматривается. В этом случае предполагается его удаление и последующее повторное определение с новыми параметрами.

Триггеры в Oracle

В Oracle возможности по созданию триггеров наиболее развитые по сравнению с другими СУБД. Поэтому в данном разделе мы кратко опишем те дополнитель­ные возможности триггеров Oracle, которые отсутствуют в стандарте SQL.

 

Заголовок триггера

Имеет дополнительную возможность, которая синтаксически выражается факуль­тативной фразой OR REPLACE:

 

CREATE [OR REPLACE] TRIGGER имя_триггера

 

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

 



Поделиться:


Последнее изменение этой страницы: 2021-05-27; просмотров: 88; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.216.34.146 (0.031 с.)