Presentations
ve Events
tablolarına sahip olduğunuzu varsayalım. Bir sunum kaydedildiğinde ve konum ve tarih gibi temel olay bilgilerini içerdiğinde, bir tetikleyici kullanılarak otomatik olarak bir olay oluşturulur. (Korkarım ki teknik nedenlerin sadece bir yerde tek bir yerde saklanması ve bir görüş kullanması imkansızdır.) Ayrıca, bu bilgiyi daha sonra sunumda değiştirirken, tetikleyici de güncellemeleri olaya aktarır. gibi pek: bir kullanıcı hiç olay bilgileri değişirse, buna da geri sunum gitmeli, böyleceTetikleyicilerin karşılıklı olarak yinelemeli yürütmesini önler misiniz?
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
Şimdi, müşteri bunu istiyor.
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
Sonuçta bu her tetikleyici birbirlerine sonra ateşe neden olur: Bilinen nedenlerden dolayı, ben ters yapamaz. Yapabileceğim şey, bir kullanıcı kimliği içeren her iki tabloya bir sütun last_edit_by
eklemektir. (Pozitif gerçek kişilerin tüm kullanıcı kimlikleri yaparak, diyelim ki, ama negatif komut kullanıcı kimlikleri) özel geçersiz kimliğe sahip tetikleyici tarafından doldurulur, bir çıkış koşulu olarak kullanıp olsaydı:
AND last_edit_by >= 0
Bu işe yarayabilecek ama yapmak istediğim, bir işlem içinde bir tetikleyicinin yalnızca bir kez ateşlenmesi gereken SQL sunucusuna işaret etmek. Bunu kontrol etmenin bir yolu var mı? Ya da belki bir tablonun bir tetikleyici tarafından etkilendiğini kontrol etmek için? Steve Robbins için
Cevap teşekkürler:
Sadece trigger_nestlevel()
denetlenirken bir IF durumda potansiyel iç içe UPDATE
ifadeleri sarın. Örneğin: trigger_nestlevel()
1-dayanıyor gibi görünüyor bu
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
Not, 0 temelli değildir. Her iki tetikleyicinin de bir kez yürütmesini, ancak daha sık olmamasını istiyorsanız, her iki tetikleyicide de trigger_nestlevel() < 3
numarasını kontrol edin.
İçiçe tetikleyiciler aslında bu veritabanı üzerinde devre dışı bırakılır kullanmayı değiştirmek gerekecektir. Benim sorunum bir tetikleme A ateşleme A ateş, A ateş değil A doğrudan. Ayar bunu engellemez. –
Bu yinelemeli tetikleyiciler, şu anda bir makinede değilim ama eminim ki sp_config ile yapılandırabileceğiniz iç içe tetikleyiciler var. Yine de bu problemle yüzleştiğim birkaç yıl oldu. –
Haklısınız; iç içe tetikleyiciler başka bir seçenektir. Ama belgelerini okuduğumda, A'dan sonra ateşlemeyi engeller, oysa A'nın ikinci kez ateş etmesini önlemek istiyorum. –