SQL VE TSQL DERS 29: INSERT, DELETE, UPDATE TRIGGER

INSERT TRIGGER

Bir tabloya yeni kayıt ekledikten sonra devreye girecek işlemler için kullanılır.
Trigger oluşturulduktan sonra, yeni eklenen her kaydı Inserted tablosunda tutmaya
başlar. Bu kayıtlar gerçek tablonun yapısal bir kopyasıdır.
Bir çok durumda, yapılan işlemlerin anlık olarak otomatik loglama
ihtiyacı duyulur. Bu ihtiyacı karşılamak için trigger kullanılabilir.
Product tablosunda yapılan her veri ekleme işlemini otomatik olarak
ProductLog tablosuna kaydedelim.
Product ve ProductLog tablolarını oluşturuyoruz önce

create table Product
(
Id int IDENTITY(1,1) PRIMARY KEY,
Name nvarchar(50),
ProductNumber nvarchar(50),
MakeFlag int,
FinishedGoodsFlag int,
SafetyStockLevel int,
ReorderPoint int,
StandartCoast int,
ListPrice int,
DaysToManuFacture int,
SellStartDate datetime,
rowguid int,
ModifiedDate datetime
)


create table ProductLog
(
ProductId int,
Name nvarchar(50),
ProductNumber nvarchar(50),
ListPrice Datetime
)

/*
ProductLog tablosunuda oluşturduk. Bu tabloda belirtilen sütunların  birebir
karşılığını, INSERTED isimli sözde tablodan alacağız.
*/

create trigger trg_ProductLog
on Product
after insert
as
begin
insert into ProductLog select Id,Name,ProductNumber,ListPrice from inserted
end

--Triggerı test etmek için veri ekleyelim
insert into Product values ('test ürün','sk-3335',1,0,500,700,0,0,3,getdate(),11,getdate())

/*
Normalde tek veri ekleme sorgusu çalıştığında ekranda 1 tane ' 1 rows affected ' mesajı yazar
Ancak bu sorguyla birlikte, iki kez ekrana '1 rows affected' yazar. Bunun nedeni ilk metin
INSERT sorgusunu belirtirken, ikinci sorgu trigger tarafından tetiklenerek, ProductLog tablosuna
eklenen veri için otomatik olarak oluşturulan ve kullanılan INSERT sorgusunun mesajıdır. 
*/
select Id,Name,ProductNumber from Product where ProductNumber='SK-3335'

select * from ProductLog

/*
Veri düzenleme ekranında yeni bir satır eklendiğinde trigger tetiklenecek ve yeni eklenen
kaydı ProductLog tablosuna loglayacaktır.
*/

DELETE TRIGGER

Delete triggerı tarafından Deleted isimli sözde tablo oluşturulur.
Deleted tablosu sadece trigger içerisinde kullanılabilir.
Deleted tablosu gerçek veri tablosundan bile silinmiş olan verileri
tutar. Bunun nedeni transaction sırasında geri alma işlemi gerçekleştirme
olasılığında rollback ile geri alanabilmesini sağlamaktır.

create trigger trg_uyeSil
on uye
after delete
as
begin
select deleted.uyeAdSoyad + ' isimli üye silinmiştir.' from deleted
end

delete uye where uye.uyeId= 9

/*
Delete işleminden sonra verinin nasıl select edilebildiği konusunu anlamak
delete triggerlarını anlamak için yeterlidir. Trigger içerisinde uye
tablosunu sorgulamak yerine, deleted tablosunu sorguladık. Çünkü uye
tablosunda(gerçek data tablosu) ilgili kayıtlar silindi. Ancak deleted tablosu,
silinen kayıtları transaction log dosyasını kullanarak tutar. Bu nedenle silinen
kayda ulaşmak için deleted tablosunu kullanabiliriz. Tabiki inserted ile görüntülenen
verinin gerçek tabloda aslının olmadığını unutmamak gerekir.
*/

UPDATE TRIGGER
Tablo üstünde kayıtlarda güncelleme olduğunda tepki vermek üzere kodlanan triggerlardır. Insert
ve Delete triggerlar gibi kendine has sözde tabloya sahip değildir. INSERTED VE DELETED tablolarının
her ikisini de kullanır. Ana tablodaki güncellenen kayıtların kopyasını Inserted tablosu, güncellemeden
önceki hallerini ise Deleted tablosu tutar.
Product tablosunda herhangi bir sütunun değeri değiştirildiğinde ModifiedDate sütunu değerini
o anki sistem tarih ve zaman bilgisiyle değiştirelim. Güncelleme işleminde, ModifiedDate sütunu
set edilmese bile, otomatik olarak o anki güncel bilgilerle değiştirilsin.

create trigger trg_UrunGuncellemeTarihiniGuncelle
on Product
after update
as
begin 
update Product set ModifiedDate =GETDATE() where Id= (Select Id from inserted)
end

select Id,Name,ProductNumber, ModifiedDate from Product where Id=2
-- Id'si 2 olan ürünü listeledik

update Product set Name ='Road-750 Red,52' where Id =2
-- Güncelleme yapar ve trigger tetikler.

select Id,Name,ProductNumber,ModifiedDate from Product where Id=2
-- Update ile sadece Name sütunu üzerinde güncelleme yapılmasına rağmen
-- trigger ile ModifiedDate sütunu da otomatik olarak güncellendi.


/*
ürünler tablosundaki kayıtlarda bir güncelleme yapıldığında, bu güncelleme
bilgilerini başka bir tabloda log olarak tutalım. Bu log tablosunda güncelleme
işleminden önceki ve sonraki veriler tutulsun.
*/

-- Güncellenecek ürünlerin özet bilgilerinin loglanacağı tabloyu oluşturalım.

create table UrunGuncellemeLog
(
Id int,
Name nvarchar(50),
ProductNumber nvarchar(50),
ModifiedDate Datetime
)

-- Oto loglama işlemini gerçekleştirecek update triggerı oluşturalım

create trigger trg_UrunGuncellemeLog
on Product
after update
as
begin
declare @Id int,
@Name nvarchar,
@ProductNumber nvarchar,
@ModifiedDate datetime

select @Id=i.Id,@Name=i.Name,@ProductNumber=i.ProductNumber,@ModifiedDate=i.ModifiedDate
from inserted as i

insert into UrunGuncellemeLog
values(@Id,@Name,@ProductNumber,@ModifiedDate)
end

--Bir ürün güncelleyelim

update Product set Name='Road-750' where Id=2

/*
Tek bir güncelleme yapılmasına rağmen UrunGuncellemeLog tablosuna 2 kayıt eklendi. Bunun
nedeni Update triggerın inserted ve deleted tablolarının her ikisinide kullanıyor olmasıdır.
İlk sıradaki kayıt verinin güncellenmeden önceki halini (deleted), ikinci kayıt ise güncelleme
sonrasındaki (inserted) yeni halini belirtir ve log olarak kaydeder.
*/

select * from UrunGuncellemeLog