मान लें कि आपके पास टेबल Presentations
और Events
है। जब कोई प्रस्तुति सहेजी जाती है और इसमें मूल ईवेंट जानकारी होती है, जैसे स्थान और दिनांक, एक ईवेंट ट्रिगर का उपयोग करके स्वचालित रूप से बनाया जाएगा। (मुझे डर है कि तकनीकी कारणों के लिए डेटा को केवल एक ही स्थान पर रखना और दृश्य का उपयोग करना असंभव है।) इसके अतिरिक्त, प्रस्तुति में बाद में इस जानकारी को बदलते समय, ट्रिगर घटनाओं को अपडेट पर कॉपी करेगा, जैसे इतना:ट्रिगर्स के पारस्परिक रूप से पुनरावर्ती निष्पादन को रोकें?
CREATE TRIGGER update_presentations
ON Presentations
AFTER UPDATE
AS
BEGIN
UPDATE Events
SET Events.Date = Presentations.Date,
Events.Location = Presentations.Location
FROM Presentations INNER JOIN Events ON Presentations.EventID = Events.ID
WHERE Presentations.ID IN (SELECT ID FROM inserted)
END
अब, ग्राहक यह चाहता है ताकि, एक यूजर कभी घटना में जानकारी परिवर्तित करता है, इसे वापस प्रस्तुति के लिए रूप में अच्छी तरह से जाना चाहिए। स्पष्ट कारणों से, मैं रिवर्स नहीं कर सकता:
CREATE TRIGGER update_events
ON Events
AFTER UPDATE
AS
BEGIN
UPDATE Presentations
SET Presentations.Date = Events.Date,
Presentations.Location = Events.Location
FROM Events INNER JOIN Presentations ON Events.PresentationID = Presentations.ID
WHERE Events.ID IN (SELECT ID FROM inserted)
END
आखिरकार, यह प्रत्येक ट्रिगर को एक-दूसरे के बाद आग लगने का कारण बनता है। मैं क्या कर सकता था एक उपयोगकर्ता आईडी युक्त दोनों टेबलों पर last_edit_by
कॉलम जोड़ें। एक विशेष अमान्य आईडी के साथ ट्रिगर द्वारा भरा तो (जैसे कि, सकारात्मक वास्तविक व्यक्तियों के सभी उपयोगकर्ता आईडी बनाकर, लेकिन नकारात्मक लिपियों के उपयोगकर्ता आईडी), मैं इस्तेमाल कर सकते हैं कि एक निकास शर्त के रूप में:
AND last_edit_by >= 0
यह काम हो सकता है , लेकिन मैं जो करना चाहता हूं वह SQL सर्वर को इंगित करता है कि, एक लेनदेन के भीतर, एक ट्रिगर केवल एक बार आग लगाना चाहिए। क्या यह जांचने का कोई तरीका है? या शायद यह जांचने के लिए कि एक तालिका पहले से ही एक ट्रिगर से प्रभावित हो चुकी है?
उत्तर स्टीव रॉबिंस के लिए धन्यवाद:
बस एक अगर हालत trigger_nestlevel()
के लिए जाँच में संभावित नेस्ट UPDATE
बयान लपेट दें। उदाहरण के लिए:
CREATE TRIGGER update_presentations
ON Presentations
AFTER UPDATE
AS
BEGIN
IF trigger_nestlevel() < 2
UPDATE Events
SET Events.Date = Presentations.Date,
Events.Location = Presentations.Location
FROM Presentations INNER JOIN Events ON Presentations.EventID = Events.ID
WHERE Presentations.ID IN (SELECT ID FROM inserted)
END
ध्यान दें कि trigger_nestlevel()
जा 1 आधारित प्रतीत होता है, न 0-आधारित। यदि आप दो ट्रिगर्स को एक बार निष्पादित करना चाहते हैं, लेकिन अधिक बार नहीं, तो दोनों ट्रिगर्स में trigger_nestlevel() < 3
देखें।
नेस्टेड चलाता वास्तव में उस डेटाबेस पर अक्षम हैं बदलने के लिए की आवश्यकता होगी। मेरी समस्या एक फायरिंग बी फायरिंग ए ट्रिगर का मामला है, एक फायरिंग ए सीधे नहीं। सेटिंग इसे रोक नहीं देती है। –
रीटर्सिव ट्रिगर्स की बात है, मैं फिलहाल एक मशीन पर नहीं हूं लेकिन मुझे यकीन है कि नेस्टेड ट्रिगर्स भी हैं जिन्हें आप sp_config के साथ कॉन्फ़िगर कर सकते हैं। हालांकि मुझे इस समस्या का सामना करने के कुछ सालों से रहा है। –
आप सही हैं; नेस्टेड ट्रिगर्स एक और विकल्प है। लेकिन जिस तरह से मैंने अपने दस्तावेज़ीकरण को पढ़ा, यह बी को ए के बाद फायरिंग से रोक देगा, जबकि मैं ए को दूसरी बार फायरिंग से रोकना चाहता हूं। –