Триггеры — это особые хранимые процедуры, автоматически выполняемые при использовании базы данных определенным образом. С любой операцией, вызывающей изменение содержимого таблицы, можно связать сопутствующее действие (триггер), которое СУБД должна выполнять при выполнении каждой такой операции.
Триггер — это обработчик который можно выполнить во время выполнения операций INSERT, UPDATE, DELETE.
Если вы программист, то это можно сравнить с событием которое возникает в ходе операции, а вот как оно будет обработано вы должны об этом позаботиться самостоятельно.
Вместе с созданием триггера постоянно создаются две служебные таблицы: inserted и deleted
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
)
DROP TRIGGER Sales.SaleaOrderDetailNotDiscontinued; -- Удаление тригеров.
--- Приминение тригеров для проверки дельты (изменения) обновления ---
--Дельта обновления - велечина изменения обновленного значения относительно предыдущего.
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