Триггеры
Далее я создал триггеры, то есть сущности, выполняющие некоторые действия при изменении данных таблиц базы.
Я создал триггер, который при удалении строки с продавцом ставит связанным с ним покупателям и заказам значение nullв поле snum.
DROP trigger if exists salespeople_DELETE;
CREATE trigger salespeople_DELETE
before DELETE on salespeople
for each row
begin
UPDATE customers set customers.snum = null
WHERE old.snum = customers.snum;
UPDATE orders set orders.snum = null
WHERE old.snum = orders.snum;
end;
Для проверки работы триггера я удалил запись в таблице продавцов.
DELETE FROM salespeople WHERE snum = 4;
В результате удаления записи и последующей работы триггера так стали выглядеть соответственно таблицы покупателей и заказов:
|
|
|
|
|
|
|
cnum |
cname |
city |
rating |
snum |
|
1 |
Василий Дубов |
Нижний Новгород |
60 |
2 |
|
2 |
Алексей Шмыга |
Нижний Новгород |
830 |
3 |
|
3 |
Лариса Тупакова |
Нижний Новгород |
520 |
3 |
|
4 |
Петр Быков |
Бор |
30 |
|
|
5 |
Антон Тотуттотам |
Бор |
120 |
|
|
|
|
|
|
|
|
onum |
odate |
amt |
cnum |
snum |
|
1 |
02.11.2006 |
610 |
1 |
3 |
|
2 |
02.11.2006 |
8255,5 |
2 |
3 |
|
3 |
15.06.2007 |
5160 |
3 |
2 |
|
4 |
05.05.2008 |
310 |
4 |
|
|
5 |
15.11.2009 |
1200 |
5 |
|
|
6 |
17.11.2009 |
15 |
5 |
|
Далее я написал триггер, который делает аналогичные действия с таблицей заказов в случае удаления записи с покупателем.
DROP trigger if exists customers_DELETE;
CREATE trigger customers_DELETE
before DELETE on customers
for each row
begin
UPDATE orders set orders.cnum = null
WHERE old.cnum = orders.cnum;
end;
Далее представлен проверочный запрос. Важно отметить, что все последующие запросы производятся без отмены запросов, связанных с проверкой предыдущих триггеров. В этому случае, например, три значения null(в виде пустых ячеек) в нижних трех строках остались на своих местах.
DELETE FROM customers WHERE cnum = 1;
Так выглядит обновленная таблица заказов:
|
|
|
|
|
|
|
onum |
odate |
amt |
cnum |
snum |
|
1 |
02.11.2006 |
610 |
|
3 |
|
2 |
02.11.2006 |
8255,5 |
2 |
3 |
|
3 |
15.06.2007 |
5160 |
3 |
2 |
|
4 |
05.05.2008 |
310 |
4 |
|
|
5 |
15.11.2009 |
1200 |
5 |
|
|
6 |
17.11.2009 |
15 |
5 |
|
Далее я написал триггер, который обрабатывает изменение записи с продавцом. Точнее: при изменении идентификатора продавца триггер меняет значение со старого на новое во всех связанных с редактируемым продавцом строках таблиц заказов и покупателей.
DROP trigger if exists salespeople_UPDATE;
CREATE trigger salespeople_UPDATE
after UPDATE on salespeople
for each row
begin
if new.snum != old.snum then
UPDATE customers set customers.snum = new.snum
WHERE customers.snum = old.snum;
UPDATE orders set orders.snum = new.snum
WHERE orders.snum = old.snum;
end if;
end;
Так выглядит проверочный запрос:
UPDATE salespeople set snum = 20 WHERE snum = 2;
Я привожу только изменившуюся таблицу заказов. Таблица покупателей осталась без изменений, так как в предыдущем проверочном запросе я удалил строку с единственным покупателем, который обслуживался изменяемым в этом запросе продавцом.
|
|
|
|
|
|
|
onum |
odate |
amt |
cnum |
snum |
|
1 |
02.11.2006 |
610 |
|
3 |
|
2 |
02.11.2006 |
8255,5 |
2 |
3 |
|
3 |
15.06.2007 |
5160 |
3 |
20 |
|
4 |
05.05.2008 |
310 |
4 |
|
|
5 |
15.11.2009 |
1200 |
5 |
|
|
6 |
17.11.2009 |
15 |
5 |
|
Далее я написал аналогичный триггер на случай изменения записи с покупателем.
DROP trigger if exists customers_UPDATE;
CREATE trigger customers_UPDATE
after UPDATE on customers
for each row
begin
if new.cnum != old.cnum then
UPDATE orders set orders.cnum = new.cnum
WHERE orders.cnum = old.cnum;
end if;
end;
Вид проверочного запроса:
UPDATE customers set cnum = 22 WHERE cnum = 2;
Изменившаяся таблица заказов:
|
|
|
|
|
|
|
onum |
odate |
amt |
cnum |
snum |
|
1 |
02.11.2006 |
610 |
|
3 |
|
2 |
02.11.2006 |
8255,5 |
22 |
3 |
|
3 |
15.06.2007 |
5160 |
3 |
20 |
|
4 |
05.05.2008 |
310 |
4 |
|
|
5 |
15.11.2009 |
1200 |
5 |
|
|
6 |
17.11.2009 |
15 |
5 |
|
Далее я написал триггер, не позволяющий выставлять продавцу значение комиссии в соответствующее поле большее, чем 0,3:
DROP trigger if exists comm_1;
CREATE trigger comm_1
before UPDATE on salespeople
for each row
begin
if new.comm > 0.3 then
set new.comm = 0.3;
end if;
end;
Попытка выставить Ивану Жадову значение комиссии, равное 0,5:
UPDATE salespeople set comm = 0.5 WHERE snum = 1;
В результате комиссия Ивана становится равной 0,3:
|
|
|
|
|
|
snum |
sname |
city |
comm |
|
1 |
Иван Жадов |
Нижний Новгород |
0,3 |
|
20 |
Федор Захапов |
Нижний Новгород |
0,15 |
|
3 |
Максим Хитров |
Нижний Новгород |
0,14 |
