Триггеры — это особые хранимые процедуры, автоматически выполняемые при использовании базы данных определенным образом. С любой операцией, вызывающей изменение содержимого таблицы, можно связать сопутствующее действие (триггер), которое СУБД должна выполнять при выполнении каждой такой операции.
Триггер — это обработчик который можно выполнить во время выполнения операций INSERT, UPDATE, DELETE.
Если вы программист, то это можно сравнить с событием которое возникает в ходе операции, а вот как оно будет обработано вы должны об этом позаботиться самостоятельно.
Вместе с созданием триггера постоянно создаются две служебные таблицы: inserted и deleted
1 2 3 4 5 6 7 8 9 10 11 12 13 |
CREATE TRIGGER Production.ProductIsRationed ON Production.ProductInventory FOR INSERT, UPDATE --тригер на 2 операции IF EXISTS ( SELECT * FROM inserted i JOIN deleted d ON d.ProductID = i.ProductID AND d.LocationID=i.LocationID WHERE (d.Quantity - i.Quantity) > d.Quantity/2 AND d.Quantity - i.Quantity > 0 ) |
1 2 |
DROP TRIGGER Sales.SaleaOrderDetailNotDiscontinued; -- Удаление тригеров. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
--- Приминение тригеров для проверки дельты (изменения) обновления --- --Дельта обновления - велечина изменения обновленного значения относительно предыдущего. SELECT * FROM Production.ProductInventory GO CREATE TRIGGER Production.ProductIsRationed ON Production.ProductInventory FOR UPDATE AS IF EXISTS ( SELECT * FROM inserted i JOIN deleted d ON d.ProductID = i.ProductID AND d.LocationID=i.LocationID WHERE (d.Quantity - i.Quantity) > d.Quantity/2 --вычисляем дельта обновление (разница между текущим количеством товара и сколько останется после продажи) AND d.Quantity - i.Quantity > 0 ) BEGIN RAISERROR('Не возможно покупать больше 50 процентов от оставшегося количества товаров ',1,2) ROLLBACK TRAN END GO SELECT * FROM Production.ProductInventory WHERE ProductID = 4 AND LocationID = 6 UPDATE Production.ProductInventory SET Quantity = 200 -- Пытаемся продать 422-200 = 222-больше 50% процентов WHERE ProductID = 4 AND LocationID = 6 UPDATE Production.ProductInventory SET Quantity = 222 -- Пытаемся продать 422-222 = 200- меньше 50% процентов WHERE ProductID = 4 AND LocationID = 6 UPDATE Production.ProductInventory SET Quantity = 422 WHERE ProductID = 4 AND LocationID = 6 GO --------------------------------------------------------------------- ---отмена действия тригеров на таблице без его удаления--- ALTER TABLE Production.ProductInventory DISABLE TRIGGER ALL ; -- отключаем тригеры GO UPDATE Production.ProductInventory SET Quantity = 200 --пытаемся продать 422-200 = 222-больше 50% процентов WHERE ProductID = 4 AND LocationID = 6 GO UPDATE Production.ProductInventory SET Quantity = 422 WHERE ProductID = 4 AND LocationID = 6 GO ALTER TABLE Production.ProductInventory ENABLE TRIGGER ALL ; -- включаем тригер GO UPDATE Production.ProductInventory SET Quantity = 200 --пытаемся продать 422-200 = 222-больше 50% процентов WHERE ProductID = 4 AND LocationID = 6 GO ---Production.ProductIsRationed - реализован правильно но не оптимизирован! -- ------------------------------------------------------------------------------ ---- Правильно так: ----- ALTER TRIGGER Production.ProductIsRationed -- ALTER TRIGGER позволяет изменить существующий тригер не удаляя его ON Production.ProductInventory FOR UPDATE AS IF UPDATE(Quantity) -- Функция UPDATE() - возвращает TRUE или FALSE в зависимости от того осуществляется ли обновление конкретного столбца. BEGIN IF EXISTS ( SELECT * FROM inserted i JOIN deleted d ON d.ProductID = i.ProductID AND d.LocationID=i.LocationID WHERE (d.Quantity - i.Quantity) > d.Quantity/2 --вычисляем дельта обновление (разница между текущим количеством товара и сколько останется после продажи) AND d.Quantity - i.Quantity > 0 ) BEGIN RAISERROR('Не возможно покупать больше 50 процентов от оставшегося количества товаров ',1,16) ROLLBACK TRAN END END GO |