3 – PL/SQL Control Statements

PaylaşTweet about this on TwitterShare on FacebookEmail this to someoneShare on Google+Share on LinkedInShare on TumblrShare on RedditPin on PinterestDigg thisFlattr the authorShare on StumbleUponBuffer this page

PL/SQL de üç tür kontrol ifadesi bulunmaktadır;
Koşullu seçim ifadeleri: Farklı değerler/durumlar için farklı işlemler yapmak istediğimiz zaman bu grupta bulunan ifadeleri kullanabiliriz. IF veya CASE ifadeleri.
Döngü ifadeleri: Belirli bir işlemi istediğimiz şartlarda istediğimiz adet kadar tekrar edecek şekilde çalıştırmak için kullandığımız yapılardır, LOOP, FOR LOOP ve WHILE LOOP ifadeleri.
Sıralı (sequential) kontrol ifadeleri: Çok fazla kullanımı olmayan, kişisel olarak başka alternatiflerin olduğu durumlarda kullanmaktan kaçındığım ifadelerdir. GOTO ve NULL ifadeleri.

Conditional Selection Statements(Koşullu seçim ifadeleri)
Koşul olarak belirttiğimiz şartlara göre farklı işlemler yapılmasını istediğimiz zaman kullandığımız ifadelerdir, IF ve CASE ifadeleri bu grupta yer almaktadır.
o IF Statement
Genel olarak;
IF THEN
IF THEN ELSE
IF THEN ELSIF
Şeklinde formları bulunur.
o CASE Statement
Genel olarak iki formu bulunur;
Simple, yani bir değeri birden fazla olası değer ile karşılaştırmak şeklinde çalışır.
Searched, birden fazla koşul bulundurup hangi koşul ile ilk olarak eşleşiliyorsa ona bağlı ifadeleri çalıştırır.

IF Statement

IF koşul THEN
Kod_bloğu
END IF;

Genel kullanımı ve syntax’ı bu şekildedir. Koşul değeri TRUE olduğu zaman “kod_bloğu” çalışacaktır, diğer durumlarda her hangi bir işlem yapılmayacatır.
Aşağıda bu temel blok için bir örnek göreceksiniz, dışarıdan aldığı satış rakamına göre satış görevlisinin başarısını değerlendirelim. Eğer 100 birimden fazla satış yapılmış ise ekrana temsilcinin başarılı olduğu bilgisini yazdıralım.


IF THEN ELSE Statement

IF koşul THEN
Kod_bloğu
ELSE
Kod_bloğu2
END IF;

IF ifadesinde yazdığımız koşul sağlanıyorsa istediğimiz blok çalışıyor demiştik, IF THEN ELSE ifadesinde ise koşulumuza uymayan durumlarda programımızın nasıl davranacağını belirtebiliyoruz.
Bir önceki örneğimizde temsilcinin 100 birimi geçmesi halinde durumunu başarılı olarak yazdırmıştık, şimdi de peki 100 birimi geçememiş ise(yani IF ten sonra yazdığımız koşul cümlesi TRUE değil ise) ne olacak bu durumu inceleyelim.

100 den büyük olma şartımız sağlanmadığı için (99) ELSE bloğuna geçilerek burada bulunan (ELSE ile END IF komutları arası) kodlarımız çalıştırılmıştır. Üstte görebileceğiniz gibi ekrana “Satış Personeli BAŞARISIZ!” mesajı yazıldı.
İhtiyacımıza göre IF ifadelerini iç içe de (nested) kullanabiliriz.

IF koşul1 THEN
Kod1
ELSE
IF koşul2 THEN
Kod2
ELSE
Kod3
END IF
END IF

IF THEN ELSIF Statement

IF koşul THEN
Kod_bloğu
ELSIF koşul2 THEN
Kod_bloğu2
ELSIF koşul3 THEN
Kod_bloğu3
ELSIF …
.
.
[ELSE ]
[kod_bloğuN]
END IF;

Şeklinde birden fazla koşul kontrol etmek ve her koşulda ayrı bir kod bloğu çalıştırmak istiyorsak bu yapıyı kullanabiliriz. Sonda bulunan ELSE ifadesi opsiyoneldir, yani hiç bir şart sağlanmıyorsa ne yapılacağını belirtmek için kullanabiliriz ancak böyle biri durum yok ise yazmayabiliriz. Tecrübelerim ELSE bloğunu yazmanızın hayrınıza olacağını gösteriyor, koşul olarak yazdığımız ifadeler günün koşullarına uygun olabiliyor ancak zamanla değişkenlik gösterebiliyor, else ifadesine koşula uymayan bir durum oluştuğunu dolayısıyla bir şeylerin yanlış gittiğini belirten ve bu durumda ne yapılması gerektiğiyle alakalı (mail atmak vs. vs.) kod yazarsak hataların önüne geçmiş oluruz.
Aslında bu ifade şekli iç içe(nested) kullanılan IF ifadesi ile aynı amaca hizmet eder ancak kod okunabilirliği adına iç içe IF yazmaktansa IF THEN ELSIF yapısını kullanmanızı tavsiye ederim.
Bir örnek ile inceleyelim, öğrencinin aldığı notlara göre derecelendirileceği bir yapımız olsun;

Gelen sınav notunu 0..100 aralığında derecelendiren bir procedure. Yukarıda da belirttiğim gibi sınav notu 0 ile 100 aralığında olmalıdır ancak kodumuzun bunun dışındaki durumlar içinde hata almadan çalışması gerekir. ELSE bloğunda 0..100 aralığının dışında bir not gelirse ekrana geçersiz sınav notu yazdırıyoruz.
NOT: RETURN komutu daha aşağıdaki kodların çalıştırılmamasını sağlamaktadır, yani RETURN komutu görüldüğü an (burada puan_degerlendir procedure’ü) program parçacığından çıkılacaktır. İlerleyen konularda bu komutu işleyeceğim.

DIKKAT
Çaylak bir yazılım geliştirici görüntüsü çizmek istemiyorsanız dikkat etmeniz gereken iki ipucu vereceğim;


Bu kullanımların sonuç açısından farkları yoktur, her iki türlüde aynı sonuçları alırsınız ancak dediğimya çaylak gibi davranmayın, tecrübenizi kodunuza yansıtın.

Simple CASE ifadesi
Bu ifade şekli IF THEN ELSIF ifadesi ile aynı yapıdadır. Genel yapısı;

CASE degisken
WHEN value1 THEN kod1
WHEN value2 THEN kod2
..
[ELSE kodELSE]
END CASE;

Şeklindedir. Yine ELSE ifadesi opsiyonel ancak ben kullanmanızı tavsiye ediyorum. CASE kelimesinden sonra gelen değer (degisken) her bir WHEN satısında bulunan değerlerle karşılaştırılır (valueX) ve hangisine uyuyorsa o satırkadı kod parçacığı çalıştırılır(kodX). Hiç bir şarta uymuyorsa ve ELSE yazmış isek o zaman kodELSE kısmına yazdığımız kısım çalıştırılır.

ELSE ifadesinin opsiyonel olduğunu belirtmek zorunda olmadığımızı yazmıştım ve yine de sizin bu ifadeyi muhakkak yazmanızı istemiştim. Bakalım ELSE ifadesini kapatıp A..E aralığında olmayan bir ifade yollandığı zaman programımız ne yapıyor.

Gördüğünüz gibi program hata verdi. Uygun CASE bulunamadı diyor. Bir önceki örnekte ‘X’ yolladığım zaman bize geçersiz bir sonuç demişti ve program başarılı çalışmıştı ama şimdiki örnekte hata alınarak sonlandı program.
Searched CASE ifadesi
Searched case ifadesinde CASE kelimesi yanında bir değişken yerine her bir koşul ifadesi WHEN kelimesinden sonra yazılır. Yazdığımız WHEN kelimesinden sonra gelen koşullardan hangisi doğru ise o şarta uygun işlemler yapılır. Yine ELSE ifadesi opsiyoneldir, yazmadığımız zaman hiç bir WHEN ifadesine uyulmayan durumda simple case ifadesinde olduğu gibi exception oluşacaktır.

ELSE ifadesinin olmadığı durumda hiç bir şart sağlanmazsa hata alacağımızı belirtmiştim bu hata durumunu da aşağıdaki gibi handle edebiliriz.

Hata yönetimini de ileriki yazılarda ele alacağım için detaylarına girmiyorum, şimdilik bu şekilde bir alternatifimiz olduğunu bilelim.

LOOP Statements (Döngü ifadeleri)
Belirli bir kod bloğunun istenilen sayı ve şartlarda tekrarlı şekilde çalıştırılması için kullanılan yapılardır. Temel olarak;
– Basic Loop
– For Loop
– Cursor For Loop
– While Loop
Formları bulunmaktadır.
Döngüler içerisinde kullanılan, EXIT, WHEN EXIT, CONTINUE, CONTINUE WHEN gibi komutlar bulunmaktadır, bu komutları da ilerleyen satırlarda anlatacağım.
Döngüleri iç içe(nested) yazabiliriz, bu durumda okunabilirliği artırmak adına döngülere label vermek şık bir tutum olacaktır. Bu konuyuda ilerde örneklerle açıklayacağım.
Döngüler konusunda dikkat edilmesi gereken bir konuda döngü içerisinde bir hata oluşması(exception) durumunda döngünün sonlanacağı yani döngüden çıkılacağıdır.
Basic Loop

[LABEL] LOOP
Kod_Blogu
END LOOP [LABEL]

En temel döngü yapısı bu şekildedir. Sonsuz döngü oluşmasını engellemek için kod_blogu içerisinde döngüden çıkılması gereken şartı ve çıkış komutunu vermemiz gerekmektedir. Burada yukarıda bahsettiğim döngü komutları devreye girecek. Öncelikle bu komutları öğrenip sonra diğer döngü komutlarını incelemeye devam edelim.
EXIT Komutu
Exit komutu içerisinde bulunduğu döngünün sonuna gitmemizi ve döngüden çıkmamızı sağlar. Eğer iç içe (nested) döngümüz var ise en yakın END LOOP satırına giderek bir üst LOOP un devam etmesini sağlar. Aşağıda bu konu için örnekler bulabilirsiniz, örnek üzerinde daha net olacaktır.

İlk döngüde her bir döngü adımında (iteration) x değeri bir artırılıyor, x 3 ten büyük olduğu zaman EXIT komutu işlenecek ve döngü sonlanacaktır. Ekran çıktısına bakarsak IF ten sonra x değerini yazdırıyoruz 1, 2, 3 yazılmış 4 olduğu zaman EXIT komutu devreye girerek DBMS satırı işlenmeden döngüden çıkılmıştır.
İkinci kısımda ise iç içe (nested) iki döngü bulunmaktadır. Dongu1 iç yani X değerlerini işleyen dongu2 ise dış yani y değerlerini işleyen döngüdür. X>2 şartı sağlandığı zaman EXIT komutu görülüyor, komut satırına dikkat edersek x 2 olduğu zaman y değeri 1 ve EXIT komutu görülüyor. Ardından içteki döngüden çıkılarak dış döngü devam ediyor. Y değeri dış döngüde 1 artırılıp tekrar iç döngü çalıştırılıyor. İç döngü aynı şekilde x > 2 olunca bitiyor. Dış döngü ise y > 2 koşulunu sağladığı an EXIT komutu devreye girerek dış döngünün sonlanmasını sağlıyor.
EXIT WHEN komutu
EXIT komutu ile aynı sonucu doğurur. Farkı syntaxından geliyor diyebiliriz. Aynı şekilde sonsuz döngüye girilmesini engellemek için EXIT WHEN satırına yazdığımız koşulun en az bir kez doğru olacağından emin olmalıyız. Bir örnek ile kullanımına bakalım, hatta üstteki EXIT komutu ile aynı çıktıyı üretecek kodu EXIT WHEN ile yazalım ve farkı görelim.

İç içe döngülerde fark ettiyseniz label kullandım. Bazen kodumuz iç içe döngüleri bir hayli barındırabiliyor, bu durumlarda okunabilirliği artırmak için bu şekilde label kullanmak doğru bir davranış olacaktır.
CONTINUE Statement
EXIT komutlarından farklı olarak CONTINUE komutu döngünün sonuna giderek bir sonraki iterasyonu çalıştırmamıza yarar. Yani exit komutu karşılaşıldığı anda döngünün sonuna gidilerek sonlandırmayı sağlarken continue komutu döngünün son satırına gidip bir oradan döngüden çıkmadan bir kez daha çalıştırılmasını sağlar.

Döngüye baktığımızda her bir döngü adımında x değerini yazdırmak istediğini görüyoruz ancak DBMS satırından önce bir koşul var, x < 3 ise CONTINUE denilmiş. Yani x < 3 ise döngünün sonuna git ve döngüye devam et demiş olduk. X < 3 olduğu sürece DBMS ve EXIT WHEN satırları çalıştırılmıyor. X 3 olduğu an IF komutu atlanarak kod bloğunun devamı çalıştırılıyor. Ekran çıktısına da bakarsak x:3 yazmış ilk olarak. CONTINUE WHEN ifadesi
EXIT, EXIT WHEN komutlarında olduğu gibi CONTINUE komutu ile aralarında syntax farkı vardır. Bu yüzden bu komut için örnek yapmayacağım.
FOR LOOP
For Loop bir index değerinin belirtilen aralıkta olduğu sürece belirli bir kod bloğunun tekrar tekrar çalıştırılması mantığı ile çalışır. Örnek sytax’ı;

[label] FOR index IN [ REVERSE ] alt_limit..üst_limit
LOOP
Kod_blogu
END LOOP [ label ];

Şeklindedir;
İndex değeri alt ve üst limitler arasında olduğu sürece her bir iteration da bir artırılarak kod_blogu çalıştırılır. REVERSE ifadesi ise döngünün alt_limitten üst_limit e doğru gitmesi yerine üst_limit değerinden alt_limit değerine doğru azalarak gelmesini sağlar.
Dikkat edilemesi gereken nokta alt ve üst limit değerlerinin doğruludur, REVERSE yazılmayan durumda alt_limit > üst_limit durumunda döngüye hiç girilmez. REVERSE komutu kullanış ise bu severde üst_limit > alt_limit olmalıdır. Aksi durumda döngü hiç çalışmayacaktır.
EXIT, EXIT WHEN, CONTINUE, CONTINUE WHEN komutları da FOR LOOP içerisinde aynı şekilde kullanılabilir.
Bir sorgu sonucunda dönen kayıt setlerinin her bir satırı için döngü de dönmek istediğimiz durumda cursor for loop kullanabiliriz. Bu konuyu ilerleyen yazılarda detaylı işleyeceğiz, şimdilik bu döngüyü anlatmayacağım.
En temel haliyle bir FOR LOOP aşağıdaki şekildedir;

Burada “idx” yani for loop index( veya loop counter diye geçer) hakkında bir kaç bilgi vermek istiyorum.
Döngü değişkeni lokal bir değişkendir, yani döngü içerisinde oluşturulup döngü dışarısından erişilemez. Aynı zamanda bu değişkeni döngü içerisinde erişip okuyabiliriz ama değerini değiştirmeye çalıştığımız zaman hata alırız. Yani read only dir.
Label kullanımının güzel bir örneği de iç içe döngülerde karşımıza çıkıyor. İç içe iki for döngümüz olduğu ve her ikisininde aynı isimde index değişkenine sahip olduğunu varsayalım. Bakalım bu durumda döngülerimizin index leri karışacakmı.

Gördüğünüz üzere döngüleri labellarmış isek label.indexAdi şeklinde istediğimiz seviyedeki index elemanına erişebiliryoruz.
Eğer döngü index elemanımız ile aynı isimli başka (döngüye göre global) değişkenlerimiz var ise döngü içerisinde bu değişkene erişmek istediğimizde kendi index elemanını okuyacaktır. Aynı şekilde label yöntemi ile dış (global) değişkene erişebiliriz.
DİKKAT: EXIT, EXIT WHEN gibi döngüleri erken sonlandırmaya yarayan komutların yalnızca içerisinde kullanıldığı döngüyü sonlandırmaya yaradığını belirtmiştim. Pek tabii birden fazla döngü bulunan yapılarda içerideki döngüde EXIT yapılmak istenip bütün döngülerden çıkmak istediğimizi durumlar olabilir bu durumda ne yapacağız onu görelim;

Gördüğünüz gibi döngülerimize label vermiş isek (dongu1, dongu2) EXIT WHEN komutunda hangi döngüyü kırmak istediğimizi verebiliyoruz. Çıktıyı incelersek dongu1 in index’i 1 değerinde kalmış ikinci kez iterate edilememiştir.
WHILE LOOP

[ label ] WHILE koşul LOOP
Kod_bloğu
END LOOP [ label ];

Yapısı yukarıdaki gibi olan bu döngüde “koşul” TRUE olduğu sürece kod_bloğu olarak yazdığımız kodların tekrar tekrar çalıştırılır.
Sonsuz döngüye girilmemesi için Koşul değerinin döngü içerisine FALSE veya NULL olması sağlanmalı veya EXIT, EXIT WHEN gibi döngü kıran bir durum komut kullanılmalıdır.
Diğer döngülerde olduğu gibi WHILE döngüsünde de CONTINUE, CONTINUE WHEN komutları kullanılabilir.

Gördüğümüz gibi WHILE kelimesinden sonra yazılan ifadenin TRUE olması durumunda döngü içerisine giriliyor, döngünün her bir çevriminde tekrar bu ifadenin durumu kontrol ediliyor ve TRUE ise devam FALSE ise döngüye girilmeden sonraki satıra geçilip program akışına devam ediliyor.
Sıralı (sequential) kontrol ifadeleri
GOTO
Kullanımı IF vb gibi daha önce anlattığım konular kadar sık olmasa ve kullanımı fazla önerilmese de böyle bir komut olduğunu bilmek ve kullanımını anlamakta fayda var.
Kontrolsüz şekilde dallanmalara sebep olduğu, okunabilirliği azalttığı için kullanımı önerilmemektedir. Akışı label ile belirttiğimiz başka bir noktadan itibaren devam ettirir.

GOTO komutu ile karşılaşıldığında program belirtilen label’ın olduğu kısıma atlamakta ve oradan sonra çalışmaya devam etmektedir.
label eklediğimiz satırdan sonra muhakkak bir satır kod olmalıdır. Yani label eklediğimiz yer kodumuzun son ifadesi olamaz. Bir IF içerisine label verilemez.

PaylaşTweet about this on TwitterShare on FacebookEmail this to someoneShare on Google+Share on LinkedInShare on TumblrShare on RedditPin on PinterestDigg thisFlattr the authorShare on StumbleUponBuffer this page
2 – PL/SQL Data Types
4 – PL/SQL Collections and Records

Your comments

Loading Facebook Comments ...

Leave a Reply