Programlama dillerinde en kullanışlı özelliklerden biri bir listeyi veya diziyi baştan sona gezmektir. C# gibi programlama dillerinde bu işlem foreach komutu yapılmaktadır. SQL Server tarafında ise bu işlem cursor yapısı ile yapılmaktadır. Aşağıdaki basit diyagram üzerinden giderek bir cursor oluşturma adımlarını inceleyerek konumuza başlayalım.
Örneğimizde sipariş detay tablosu, faturakod alanı üzerinden sipariş tablosuna bağlıdır. Oluşturacağımız cursor örneğinde sipariş tablosunu baştan sona dolaşarak sipariş detay tablosundan siparişin toplam maliyetini hesaplayıp sipariş tablosundaki alana işleyeceğiz.
Kodumuzun başında işlemde kullanacağımız değişkenleri tanımlıyoruz.
declare @_faturaKod int declare @_toplam float
Gerekli değişkenleri tanımladıktan sonra cursorumuzu tanımlayabiliriz.
declare cursor_ad cursor for select faturaKod from tblSiparis
Burada for ifadesinden sonra gelen sql sorgusu tablonun hangi sorgu ile dönüleceğini göstermektedir. Biz örneğimizde konuyu daha basit tutmak için sorgumuzu tek tablo ve kolon seçimi üzerinden oluşturduk. Cursor tanımlandıktan sonra işleme başlamak için cursorumuzu açmamız gerekmektedir.
open cursor_ad
Cursoru yukarııdaki komut ile açtıktan sonra işaretçimizi tabloda sonraki satıra konumlandırmak için fetch işlemi yapıyoruz.
fetch next from cursor_ad into @_faturaKod
fetch işlemi ile sıradaki satır tablodan okunurken select içerisinde okunan değerler sırası ile into ifadesinden sonraki değişkenlere atanır. Örneğin select ifademiz select a,b from … şeklinde olsaydı into ifadesinden sonra da bu değerlere karşılık iki değişken gösterilmeliydi. Fetch işlemi başarılı sonuç döndüğünde @@FETCH_STATUS sistem değişkeninin değeri sıfır olur. Bu sebeple aşağıdaki while şartı ile bütün tablonun okunması sağlanır.
while @@FETCH_STATUS = 0 begin
while içerisinde gerekli operasyonel işlemler yapılır. Örneğimizdeki sipariş detay tablosundan toplam değeri okuyoruz. Daha sonra sipariş tablosunda değeri güncelliyoruz.
select @_toplam = sum(toplam) from tblSiparisDetay where faturaKod = @_faturaKod update tblSiparis set toplam = @_toplam where faturaKod = @_faturaKod
Gerekli işlemler yapıldıktan sonra while döngüsünün sonsuz döngüye girmemesi için while bloğunun son satırı olarak fetch işlemi tekrar edilir. While bloğu aşağıdaki gibi olur.
while @@FETCH_STATUS = 0 begin select @_toplam = sum(toplam) from tblSiparisDetay where faturaKod = @_faturaKod update tblSiparis set toplam = @_toplam where faturaKod = @_faturaKod fetch next from cursor_ad into @_faturaKod end
While döngüsünün sonlanması bütün tablonun okunmuş olduğunu gösterir. Son işlem olarak da cursoru kapatıp daha sonra hafızadan tamamen silmemiz gerekmektedir.
close cursor_ad deallocate cursor_ad
Toplu olarak bütün kod aşağıdaki gibi olur.
declare @_faturaKod int declare @_toplam float declare cursor_ad cursor for select faturaKod from tblSiparis open cursor_ad fetch next from cursor_ad into @_faturaKod while @@FETCH_STATUS = 0 begin select @_toplam = sum(toplam) from tblSiparisDetay where faturaKod = @_faturaKod update tblSiparis set toplam = @_toplam where faturaKod = @_faturaKod fetch next from cursor_ad into @_faturaKod end close cursor_ad deallocate cursor_ad