Bir veritabanı tetikleyicim var:
CREATE TRIGGER setDescToUpper
ON part_numbers
AFTER INSERT,UPDATE
AS
DECLARE @PnumPkid int, @PDesc nvarchar(128)
SET @PnumPkid = (SELECT pnum_pkid FROM inserted)
SET @PDesc = (SELECT UPPER(part_description) FROM inserted)
UPDATE part_numbers set part_description_upper = @PDesc WHERE pnum_pkid=@PnumPkid
GO
Bu kötü bir fikir mi? Yani aynı tablodaki bir sütunu güncellemek için. Hem ekleme hem de güncelleme için ateşlenmesini istiyorum.
Çalışıyor, sadece döngüsel bir durumdan korkuyorum. Güncelleme, tetikleyicinin içinde, tetikleyiciyi ateşler ve tekrar ve tekrar. **Bu olacak mı?
Lütfen, büyük harf olayına takılmayın. Çılgınca bir durum.
DB'de ayarlanmış olan tetikleyiciler için özyineleme düzeyine bağlıdır.
Eğer bunu yaparsan:
SP_CONFIGURE 'nested_triggers',0
GO
RECONFIGURE
GO
Ya da bunu:
ALTER DATABASE db_name
SET RECURSIVE_TRIGGERS OFF
Yukarıdaki tetikleyici bir daha çağrılmaz ve güvende olursunuz (bir tür kilitlenmeye girmediğiniz sürece; bu mümkün olabilir ama belki de yanılıyorumdur).
Yine de bunun iyi bir fikir olduğunu düşünmüyorum. Daha iyi bir seçenek TETİKLEYİCİ YERİNE kullanmak olacaktır. Bu şekilde DB üzerinde ilk (manuel) güncellemeyi yürütmekten kaçınmış olursunuz. Yalnızca tetikleyicinin içinde tanımlanan güncelleme yürütülür.
INSTEAD OF INSERT tetikleyicisi şu şekilde olacaktır:
CREATE TRIGGER setDescToUpper ON part_numbers
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO part_numbers (
colA,
colB,
part_description
) SELECT
colA,
colB,
UPPER(part_description)
) FROM
INSERTED
END
GO
Bu, part_description
alanına uygulanan açık bir UPPER çağrısı ile orijinal INSERT ifadesini otomatik olarak "replace" yapacaktır.
Bir INSTEAD OF UPDATE tetikleyicisi de benzer olacaktır (ve tek bir tetikleyici oluşturmanızı tavsiye etmiyorum, bunları ayrı tutun).
Ayrıca, bu @Martin'in yorumunu da ele almaktadır: çok satırlı eklemeler/güncellemeler için çalışır (sizin örneğinizde çalışmaz).
Evet... ilk ekleme işleminde değeri ayarlayabileceğiniz bir tabloyu güncellemek için ek bir adıma sahip olmak muhtemelen fazladan, önlenebilir bir işlemdir. UPPER(part_description) değerini kullanarak part_description_upper sütununa sadece part_description değerini ekleyebileceğiniz orijinal insert deyimine erişiminiz var mı?
Düşündükten sonra, muhtemelen bunu yapmış olacağınız için erişiminiz yok, bu yüzden bazı seçenekler de sunmalısınız...
Bu part_description_upper sütununa olan ihtiyaca bağlıdır, eğer sadece "görüntüleme" içinse, o zaman sadece döndürülen part_description değerini ve "ToUpper()" kullanabilir (programlama diline bağlı olarak).
"realtime" işleminden kaçınmak istiyorsanız, düşük trafik dönemlerinde günde bir kez değerlerinizi gözden geçirmek için bir sql işi oluşturabilir ve şu anda ayarlanmamış olanlar için bu sütunu UPPER part_description değerine güncelleyebilirsiniz.
tetikleyicinizle gidin (ve diğerlerinin de belirttiği gibi tekrarlamaya dikkat edin)...
HTH
Dave
Evet, özyinelemeli tetikleyiciler ayarını kapatmadığınız sürece tetikleyicinizi özyinelemeli olarak çağıracaktır:
ALTER DATABASE db_name SET RECURSIVE_TRIGGERS OFF
MSDN, http://msdn.microsoft.com/en-us/library/aa258254(SQL.80).aspx adresinde Özyinelemeli Tetikleyiciler başlığı altında davranışla ilgili iyi bir açıklamaya sahiptir.