Читайте также:
|
|
Триггеры активизируются при выполнении оператора DML. Алгоритм выполнения оператора DML таков:
1. Выполняются операторные триггеры BEFORE (при их наличии).
2. Для каждой строки, на которую воздействует оператор:
a. Выполняются строковые триггеры BEFORE (при их наличии).
b. Выполняется собственно оператор.
c. Выполняются строковые триггеры AFTER (при их наличии).
3. Выполняются операторные триггеры AFTER (при их наличии).
В качестве примера создадим различные триггеры UPDATE для таблицы classes. Мы создадим три строковых триггера BEFORE и два операторных триггера AFTER:
CREATE SEQUENCE trig_seq
START WITH 1
INCREMENT BY 1;
CREATE OR REPLACE PACKAGE TrigPackage AS
-- Глобальный счетчик для использования в триггерах
v_Counter NUMBER;
END TrigPackage;
CREATE OR REPLACE TRIGGER classesBStatement
BEFORE UPDATE ON classes
BEGIN
-- Сначала сбросим счетчик.
TrigPackage.v_Counter:= 0;
INSERT INTO temp_table (num_col, char_col)
VALUES (trig_seq.NEXTVAL,
'Before Statement: counter = ' | I TrigPackage.v_Counter);
-- А теперь увеличим его значение для следующего триггера.
TrigPackage.v_Counter:= TrigPackage.v_Counter+ 1;
END ClassesBStatement;
CREATE OR REPLACE TRIGGER ClassesAStatementl
AFTER UPDATE ON classes
BEGIN
INSERT INTO temp_table (num_col. char_col)
VALUES (trig'_seq.NEXTVAL,
'After Statement 1: counter = ' | TrigPackage.v_Counter);
-- Увеличим для следующего триггера.
TrigPackage.v_Counter:= TrigPackage.v_Counter+ 1;
END ClassesAStatementl;
CREATE OR REPLACE TRIGGER ClassesAStatement2
AFTER UPDATE ON classes
BEGIN
INSERT INTO temp_table (num_col, char_col)
VALUES (trig_seq.NEXTVAL,
'After Statement 2: counter = ' || TrigPackage.v_Counter);
-- Увеличим для следующего триггера.
TrigPackage.v_Counter:= TrigPackage.v_Counter+ 1;
END ClassesAStatement2;
CREATE OR REPLACE TRIGGER ClassesBRowl
BEFORE UPDATE ON classes
FOR EACH ROW
BEGIN
INSERT INTO temp_table (num_col, char_col)
VALUES (trig_seq.NEXTVAL,
'Before Row 1: counter = ' || TrigPackage.v_Counter);
-- Увеличим для следующего триггера.
TrigPackage.vJDounter:= TrigPackage.v_Counter+ 1;
END ClassesBRowl;
CREATE OR REPLACE TRIGGER ClassesBRow2
BEFORE UPDATE ON classes
FOR EACH ROW
BEGIN
INSERT INTO temp_table (num_col, char__col)
VALUES (trig_seq.NEXTVAL,
'Before Row 2: counter = ' | TrigPackage.v_Counter);
-- Увеличим для следующего триггера.
TrigPackage.v_Counter:= TrigPackage.v_Counter+ 1;
END ClassesBRow2;
CREATE OR REPLACE TRIGGER ClassesBRowS
BEFORE UPDATE ON classes
FOR EACH ROW
BEGIN
INSERT INTO temp_table (num_col, char_col)
VALUES (trig_seq.NEXTVAL,
'Before Row 3: counter = ' || TrigPackage.v_Counter);
-- Увеличим для следующего триггера.
TrigPackage.v_Counter:= TrigPackage,v_Counter+ 1;
END ClassesBRowS;
CREATE OR REPLACE TRIGGER ClassesARow
AFTER UPDATE ON classes
FOR EACH ROW
BEGIN
INSERT INTO temp_table (num_col, char_col)
VALUES (trig_seq.NEXTVAL,
'After Row: counter = ' || TrigPackage.v_Counter);
-- Увеличим для следующего триггера.
TrigPackage.v_Counter:= TrigPackage.v_Counter+ 1;
END ClassesARow;
Выполним следующий оператор UPDATE:
UPDATE classes
SET num_credits = 4
WHERE department IN ('HIS', ' C S ');
Этот оператор воздействует на четыре строки. Операторные триггеры BEFORE и AFTER выполняются по разу, а строковые триггеры BEFORE и AFTER — по четыре раза. Если после этого считать информацию в temp_table, то будет получено следующее:
SELECT * FROM temp_table
ORDER BY num_col;
NUM_COL CHAR_COL
-------------- -------------------------
1 Before Statement: counter = 0
2 Before Row 3: counter = 1
3 Before Row 2: counter = 2
4 Before Row 1: counter = 3
5 After Row: counter = A
6 Before Row 3: counter = 5
7 Before Row 2: counter = 6
8 Before Row 1: counter = 7
9 After Row: counter = 8
10 Before Row 3: counter = 9
11 Before Row 2: counter = 10
12 Before Row 1: counter = 11
13 After Row: counter = 12
14 Before Row 3: counter = 13
15 Before Row 2: counter = 14
16 Before Row 1: counter = 15
17 After Row: counter = 16
18 After Statement 2: counter = 17
19 After Statement 1: counter = 18
При активизации каждого из триггеров будут видны изменения, сделанные предыдущими триггерами, а также изменения в базе данных, внесенные оператором. Для этого каждый триггер выводит значение счетчика.
Порядок, в котором активизируются триггеры одного вида, не определен. Из приведенного примера следует, что каждый триггер видит изменения, вносимые более ранними триггерами. Если порядок важен, следует объединить все операции в один триггер.
При создании журнала моментальных снимков таблицы Oracle w автоматически создает для нее строковый триггер AFTER ROW, обновляющий этот журнал после каждого оператора DML Следует учитывать этот факт при создании дополнительного строкового триггера AFTER для данной таблицы. Существуют и другие ограничения на использование триггеров и моментальных снимков (известных как материализованные представления в Oracle®).
Дата добавления: 2014-12-19; просмотров: 35 | Поможем написать вашу работу | Нарушение авторских прав |