20 Nisan 2011 Çarşamba

SQL Output Kavramı

Bu yazımızda insert, update ve delete işlemleri için arka planda yapılan işlemleri inceliyor olacağız. SQL’de bu komutları yazdığımız an, arka planda otomatik olarak bir transaction başlatılır (bizim ele aldığımız durumlar hariç). Bu transaction içerisinde, yine arka planda sanal olarak “inserted” ve “deleted” tablosu oluşturulur. Kodumuzu çalıştırdığımız zaman da, bu transaction kapatılarak işlem sonlanır.

Normal şartlarda, bu sanal tabloları sadece trigger’lar içerisinde kullanabiliyorduk. Ancak SQL Server 2005’den itibaren,  bu tabloları, yazdığımız kodlar içerisinde ele alabilmemiz mümkün hale geldi. Şimdi de bu tabloların ne amaçla kullanıldıklarını anlamaya çalışalım.

INSERT => Insert etmeye çalıştığımız data, ilk olarak arka plandaki sanal olarak oluşan ‘inserted’ tablosuna gider. Buradan da insert etmek istediğimiz tabloya kaydedilir ve oluşan bu sanal tablo, SQL belleğinden düşer.

DELETE => Silmek istediğimiz data, ilk olarak arka plandaki sanal olarak oluşan ‘deleted’ tablosuna gider. Daha sonra silinir ve ‘deleted’ tablosu SQL belleğinden düşer.

UPDATE => Update etmek istediğimiz datanın eski hali ‘deleted’ tablosuna gider, yeni hali de ‘inserted’ tablosuna kaydedilir. Daha sonra datanın son hali, içerisinde bulunduğu tablo içerisine kaydedilir ve data güncellenmiş olur.

'‘inserted’ ve ‘deleted’ tablolarına, trigger yazarken ihtiyaç duyarız. Çünkü insert, update ve delete işlemleri yapıldığında, başka bir işi tetiklemek isteyebiliriz. Dolayısı ile oluşan datalara ihtiyaç duyarız. Şimdi örnek üzerinde inceleme yapalım.

Üzerinde çalışabileceğimiz basit bir tablo tasarlayarak örneğimize başlayalım.

CREATE TABLE Personel

(

      PersonelId INT IDENTITY(1,1),

      AdSoyad NVARCHAR(100),

      Maas MONEY

)

ilk olarak insert işlemi sırasında, inserted tablosundaki dataları gösterelim. Bir tablo oluşturarak, inserted tablosundaki kayıtları buraya kopyalayacağız. Girişte de bahsettiğimiz gibi, insterted tablosu geçici bir tablodur. İşlem tamamlandığında SQL belleğinde tutulmaz.

DECLARE @Kaydedilenler TABLE

(

      PersonelId INT,

      AdSoyad NVARCHAR(100),

      Maas MONEY

)

 

INSERT INTO Personel

      OUTPUT inserted.PersonelId, inserted.AdSoyad, inserted.Maas INTO @Kaydedilenler

VALUES('Ali Deneme',100)

 

SELECT * INTO InsertTablomuz FROM @Kaydedilenler

SELECT * FROM InsertTablomuz

@Kaydedilenler adında bir tablo tanımladık. Daha sonra insert ettiğimiz datayı, sanal tablo olan ‘inserted’dan bu tabloya attık. Buradan da bulk copy yaparak, @Kaydedilenlerdeki datayı kalıcı olarak saklamak amacı ile ‘InsertTablomuz’ adlı tabloya attık. Yukarıdaki kodu çalıştırdığımızda karşımıza gelecek ekran görüntüsü, ‘InsertTablomuz’ adlı tablonun görüntüsü olacaktır. Personel tablosuna insert ettiğimiz data, aynı zamanda ‘InsertTablomuz’ adlı tabloda da kayıtlı durumdadır.

NOT: ‘InsertedTablomuz’ adlı tabloyu manuel olarak tanımlamadık. Bulk copy yaparak, @Kaydedilenler adlı tablo birebir ile aynı kolonlara ve aynı dataya sahip halde oluşturduk.

Şimdi de delete işlemi için bir örnek yapalım. Yukarıdaki insert işleminin ardından, Personel tablosunda PersonelID’si 1 ve Adı ‘Ali Deneme’ olan bir kayıt mevcuttur. Bu kaydı silip, deleted tablosundan da faydalanarak ‘SilinenlerTablomuz’ adlı tabloya atalım.

DECLARE @Silinenler TABLE

(

      PersonelId INT,

      AdSoyad NVARCHAR(100),

      Maas MONEY

)

 

DELETE Personel

      OUTPUT deleted.PersonelId, deleted.AdSoyad, deleted.Maas INTO @Silinenler

WHERE PersonelId=1

 

SELECT * INTO SilinenlerTablomuz FROM @Silinenler

 

SELECT * FROM SilinenlerTablomuz

Bu işlemin ardından, Personel tablosundaki kaydın silindiğini görebiliriz. Ancak yaptığımız işlemler sayesinde silinen bu data ‘SilinenlerTablomuz’ adlı tabloya kaydedilmiştir. (‘SilinenlerTablomuz’, bulk copy ile oluşturuldu.)

Şimdi de update işlemi için bir örnek ele alalım. Personel tablosuna birkaç tane insert yapalım.

INSERT INTO Personel VALUES('Ali Deneme',1000)

INSERT INTO Personel VALUES('Ayşe Test',2000)

INSERT INTO Personel VALUES('Fatma Tost',1400)

INSERT INTO Personel VALUES('Veli Deneme',5000)

Tüm personellerin maaşına 500 TL zam yapmak isteyelim. Ancak yaptığımız bu değişikliğin başka bir tabloda tutulmasını da istiyoruz. (Eski maaş, yeni maaş ve tarih bilgileri ile birlikte)

DECLARE @ZamTablo TABLE

(

      PersonelId INT,

      AdSoyad NVARCHAR(100),

      EskiMaas MONEY,

      YeniMaas MONEY,

      Tarih DATETIME

)

 

UPDATE Personel SET Maas=Maas+500

      OUTPUT inserted.PersonelId,inserted.AdSoyad,deleted.Maas [Eski Maas],inserted.Maas [Yeni Maas],GETDATE() INTO @ZamTablo

 

SELECT * INTO ZamListesi FROM @ZamTablo

 

SELECT * FROM ZamListesi

Burada dikkat edilmesi gereken kısım, OUTPUT anahtar sözcüğünden sonra yazdığımız kısımdır. Oluşturduğumuz @ZamTablo adlı değişkene deleted ve inserted tablosundan data alıyoruz. PersonelId ve AdSoyad zaten bu iki tabloda da aynı olduğundan, bu bilgileri inserted veya deleted tablosundan çekmemiz sonucu değiştirmez. Ancak maaş bilgisi update edilen kolondur. Girişte bahsettiğimiz gibi, update durumunda eski datalar deleted tablosuna, yeni datalar da inserted tablosuna kaydolur. PersonelId’si 1 olan kayıt için konuşursak, deleted tablosunda “1,Ali Deneme,1000” datası mevcuttur. inserted tablosunda ise datanın update edilmiş hali, yani ‘1,Ali Deneme,1500’ datası mevcuttur. Bu sebepten dolayı eski maaşı deleted  tablosundan, yeni maaşı ise inserted  tablosundan elde ettik.

Bahsi geçen sanal tablolardan data aktarımlarını bu şekilde yapabilmek mümkün. Ama başta da söylediğimiz gibi, bu tablolara çoğunlukla trigger yazarken ihtiyaç duyarız. Yukarıda bahsettiğimiz çalışma mantığını kavrayabilmemiz, trigger’ları ele alırken işimizi kolaylaştıracaktır.



0 yorum:

Yorum Gönder