11 Mart 2013 Pazartesi

MS SQL'de Döngüler

Merhaba Webkolog takipçileri!

SQL Server'da çoğu zaman sorgularımızla veri setleri üzerinde toplu işlemler yaparız. Ancak bazen, belirli bir koşul sağlanana kadar tekrar tekrar çalışması gereken veya adım adım ilerlemesi gereken senaryolarla karşılaşabiliriz. İşte bu gibi durumlarda, diğer programlama dillerinde olduğu gibi T-SQL'de de döngüler imdadımıza yetişiyor. Bugün sizlerle, MS SQL'deki en temel döngü yapısı olan WHILE döngüsünü ve nasıl kullanıldığını keşfedeceğiz. Hazırsanız, tekrarlayan görevleri otomatikleştirmeye başlayalım!

Döngüler Nedir ve Neden Kullanılır?

Döngüler, belirli bir kod bloğunun, tanımlanmış bir koşul doğru olduğu sürece veya belirli bir sayıya ulaşana kadar tekrar tekrar çalışmasını sağlayan kontrol yapılarıdır. SQL'de döngüler, genellikle aşağıdaki senaryolarda işimize yarar:

  • Belirli bir koşul karşılanana kadar tekrar eden işlemler.
  • Karmaşık veri işleme algoritmaları.
  • Veri tabanında toplu veri güncellemeleri veya eklemeleri yaparken adım adım ilerleme.
  • Özel raporlama veya veri temizleme görevleri.

Unutmamak gerekir ki, SQL Server veri setleri üzerinde işlem yapmak için optimize edilmiştir. Bu yüzden mümkün olduğunca set tabanlı (yani döngü kullanmadan) çözümler üretmek genellikle daha performanslıdır. Ancak bazı durumlarda döngüler kaçınılmaz veya daha okunur bir çözüm sunabilir.

WHILE Döngüsü: Koşul Sağlandıkça Tekrarla

MS SQL'de en sık kullanılan döngü yapısı WHILE döngüsüdür. WHILE döngüsü, belirli bir koşul doğru (TRUE) olduğu sürece içerisindeki kod bloğunu çalıştırmaya devam eder. Koşul yanlış (FALSE) olduğunda döngü sonlanır.

Temel WHILE Kullanımı

Bir WHILE döngüsü tanımlamak için WHILE anahtar kelimesi, ardından parantez içinde bir koşul ve döngü içinde çalışacak kod bloğunu belirten BEGIN ve END anahtar kelimeleri kullanılır.

-- Basit bir WHILE döngüsü örneği
DECLARE @Sayac INT = 1;

WHILE (@Sayac <= 5)
BEGIN
    PRINT 'Sayı: ' + CAST(@Sayac AS NVARCHAR);
    SET @Sayac = @Sayac + 1; -- Döngüden çıkmak için sayacı artırmayı unutmayın!
END;

Yukarıdaki örnekte, @Sayac değişkeni 1'den başlayarak her döngüde bir artırılır. @Sayac 5'ten küçük veya eşit olduğu sürece döngü çalışmaya devam eder. @Sayac 6 olduğunda koşul (@Sayac <= 5) yanlış olacağı için döngü sona erer.

BREAK ve CONTINUE Kullanımı

Döngüler içinde akışı kontrol etmek için BREAK ve CONTINUE anahtar kelimelerini kullanabiliriz:

  • BREAK: Döngüyü tamamen sonlandırır ve kontrolü döngünün hemen dışındaki ilk ifadeye aktarır.
  • CONTINUE: Döngünün mevcut iterasyonunu atlar ve koşulu yeniden değerlendirmek üzere döngünün başına döner. Yani, mevcut iterasyonda CONTINUE'den sonraki kodlar çalıştırılmaz.
-- BREAK ve CONTINUE ile WHILE döngüsü
DECLARE @i INT = 0;

WHILE (@i < 10)
BEGIN
    SET @i = @i + 1;

    IF (@i = 3)
    BEGIN
        CONTINUE; -- i 3 olduğunda bu iterasyonu atla, yani 'Sayı 3' yazmayacak
    END;

    PRINT 'Sayı: ' + CAST(@i AS NVARCHAR);

    IF (@i = 7)
    BEGIN
        BREAK; -- i 7 olduğunda döngüyü tamamen sonlandır
    END;
END;

PRINT 'Döngü bitti.';

Yukarıdaki kod çalıştırıldığında, çıktı şu şekilde olacaktır:

Sayı: 1
Sayı: 2
Sayı: 4
Sayı: 5
Sayı: 6
Sayı: 7
Döngü bitti.

Gördüğünüz gibi, 'Sayı: 3' çıktısı CONTINUE nedeniyle atlandı ve 'Sayı: 7' çıktısından sonra BREAK nedeniyle döngü sona erdi, yani 8, 9, 10 sayıları basılmadı.

WHILE Döngüsü ile Gerçek Dünya Senaryosu: Toplu Güncelleme

Basit bir toplu güncelleme senaryosu düşünelim. Diyelim ki, her seferinde 100 kaydı güncelleyerek büyük bir tablodaki performansı etkilemeden işlem yapmak istiyoruz:

-- Örnek bir tablo oluşturalım
CREATE TABLE BuyukTablo (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    Durum VARCHAR(100) DEFAULT 'Beklemede',
    IslemTarihi DATETIME NULL
);

-- Test verisi ekleyelim
INSERT INTO BuyukTablo (Durum) VALUES ('Beklemede');
GO 1000 -- 1000 satır ekle

DECLARE @ToplamGuncellenenSatir INT = 0;
DECLARE @GuncellenenBatch INT;

WHILE (EXISTS(SELECT 1 FROM BuyukTablo WHERE Durum = 'Beklemede'))
BEGIN
    -- Her seferinde 100 kaydı güncelle
    UPDATE TOP (100) BuyukTablo
    SET Durum = 'Tamamlandı',
        IslemTarihi = GETDATE()
    WHERE Durum = 'Beklemede';

    SET @GuncellenenBatch = @@ROWCOUNT; -- Son işlemde etkilenen satır sayısını al
    SET @ToplamGuncellenenSatir = @ToplamGuncellenenSatir + @GuncellenenBatch;

    PRINT CAST(@GuncellenenBatch AS NVARCHAR) + ' satır güncellendi. Toplam: ' + CAST(@ToplamGuncellenenSatir AS NVARCHAR);

    -- Eğer son batch'te hiç satır güncellenmediyse döngüyü kır (sonsuz döngüden kaçınmak için)
    IF (@GuncellenenBatch = 0)
    BEGIN
        BREAK;
    END;

    -- Küçük bir bekleme (opsiyonel, sunucu yükünü azaltmak için)
    WAITFOR DELAY '00:00:00.100'; -- 100 milisaniye bekle
END;

PRINT 'Tüm bekleyen kayıtlar güncellendi. Toplam güncellenen: ' + CAST(@ToplamGuncellenenSatir AS NVARCHAR);

-- Temp tabloyu temizleyelim
DROP TABLE BuyukTablo;

Bu örnekte, WHILE döngüsünü kullanarak TOP (100) ile her seferinde sadece 100 bekleyen kaydı güncelledim. Bu, özellikle çok büyük tablolar üzerinde işlem yaparken sunucuyu kilitlemeden ve performans sorunları yaşamadan işlemi tamamlamanın iyi bir yoludur.

MS SQL'de WHILE döngüsü, belirli senaryolarda oldukça güçlü bir araç olsa da, her zaman ilk tercihiniz olmamalıdır. Unutmayın, set tabanlı işlemler genellikle daha performanslıdır. Ancak adım adım işlem gerektiren veya karmaşık iş mantığı içeren durumlarda, WHILE döngüsü size esneklik ve kontrol sağlar. Doğru yerde ve doğru şekilde kullanıldığında, kodlarınızı çok daha yetenekli hale getirebilirsiniz!

Webkolog'u takipte kalın!

Hepinize bol kodlu ve başarılı projeler dilerim!

0 yorum:

Yorum Gönder