Proč nepoužít INSTEAD OF
spoušť? Vyžaduje to trochu více práce (jmenovitě opakované UPDATE
prohlášení), ale kdykoli můžete zabránit práci, místo abyste ji nechali, aby se stala a pak ji vrátila zpět, budete na tom lépe.
CREATE TRIGGER [dbo].[Item_BeforeUpdate_AnyBilled]
ON [dbo].[Item]
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS
(
SELECT 1 FROM inserted i
JOIN deleted AS d ON i.ItemId = d.ItemId
WHERE d.BillId IS NULL -- it was NULL before, may not be NULL now
)
BEGIN
UPDATE src
SET col1 = i.col1 --, ... other columns
ModifiedDate = CURRENT_TIMESTAMP -- this eliminates need for other trigger
FROM dbo.Item AS src
INNER JOIN inserted AS i
ON i.ItemId = src.ItemId
AND (criteria to determine if at least one column has changed);
END
ELSE
BEGIN
RAISERROR(...);
END
END
GO
Tohle se úplně nehodí. Kritéria, která jsem vynechal, jsou z nějakého důvodu vynechána:může být složité určit, zda se hodnota sloupce změnila, protože závisí na datovém typu, zda sloupec může být NULL atd. AFAIK vestavěné spouštěcí funkce může zjistit pouze to, zda byl zadán určitý sloupec, nikoli to, zda se hodnota skutečně změnila oproti předchozímu.
UPRAVIT vzhledem k tomu, že vás znepokojují pouze ostatní sloupce, které jsou aktualizovány kvůli spouštěči po, myslím, že následující INSTEAD OF
spouštěč může nahradit oba vaše stávající spouštěče a také se vypořádat s několika aktualizovanými řádky najednou (některé, aniž by splňovaly vaše kritéria):
CREATE TRIGGER [dbo].[Item_BeforeUpdate_AnyBilled]
ON [dbo].[Item]
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE src SET col1 = i.col1 --, ... other columns,
ModifiedDate = CURRENT_TIMESTAMP
FROM dbo.Item AS src
INNER JOIN inserted AS i
ON src.ItemID = i.ItemID
INNER JOIN deleted AS d
ON i.ItemID = d.ItemID
WHERE d.BillID IS NULL;
IF @@ROWCOUNT = 0
BEGIN
RAISERROR(...);
END
END
GO