INSTEAD OF
. का उपयोग क्यों न करें चालू कर देना? इसके लिए थोड़ा और काम करने की आवश्यकता है (अर्थात् दोहराया गया UPDATE
स्टेटमेंट) लेकिन किसी भी समय आप काम को रोक सकते हैं, इसे होने देने और फिर इसे वापस करने के बजाय, आप बेहतर होने जा रहे हैं।
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
ये बिल्कुल फिट नहीं बैठता। मेरे द्वारा छोड़े गए मानदंड किसी कारण से छोड़े गए हैं:यह निर्धारित करना जटिल हो सकता है कि कॉलम मान बदल गया है, क्योंकि यह डेटाटाइप पर निर्भर करता है, क्या कॉलम न्यूल हो सकता है, आदि। अंतर्निहित ट्रिगर फ़ंक्शंस AFAIK केवल यह बता सकता है कि क्या एक निश्चित कॉलम निर्दिष्ट किया गया था, यह नहीं कि मान वास्तव में पहले से बदल गया है या नहीं।
संपादित करें यह देखते हुए कि आप केवल उन अन्य स्तंभों के बारे में चिंतित हैं जो बाद के ट्रिगर के कारण अपडेट किए गए हैं, मुझे लगता है कि निम्नलिखित INSTEAD OF
ट्रिगर आपके दोनों मौजूदा ट्रिगर को बदल सकता है और एक साथ अपडेट की गई कई पंक्तियों से भी निपट सकता है (कुछ आपके मानदंडों को पूरा किए बिना):
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