You are on page 1of 281

Veri Tabanı Yönetim Sistemleri (VTYS), birbirleriyle ilişkili veri

ve programlar topluluğundan oluşmaktadır. Veri topluluğu bir "veri tabanı" olarak


değerlendirilir. Veri tabanı, bir kuruluşa ilişkin bilgilerin yer aldığı ortamdır. Veri tabanı

1
sistemleri, veri kümelerinin düzenli biçimde tutulduğu ve bu verilerin çeşitli yazılımlar
aracılığıyla yönetildiği ortamlardır.

Bu derste “veri tabanı programlama” konusunda bazı ileri konulara yer verilmektedir. Veri
tabanı programlama, özellikle uygulama geliştiricilerin başvurdukları bir yoldur. Bir takım
veri tabanı nesneleri bu yolla tanımlanarak, farklı programlarda yeniden
kullanılabilmektedir. Özellikle fonksiyonlar, yordamlar ve paketlerin yaratılması önem
taşımaktadır.

Veri tabanı programlama, veri tabanı bağımlıdır. Bunun anlamı, her veri tabanı yazılımının
kendi özel programlama dili bulunmaktadır. Bu derste, ORACLE veri tabanı göz önüne
alınmış ve onun PL/SQL veri tabanı programlama dili üzerinde durulmuştur.

İleri veri tabanı kavramlarını anlayabilmek için, öncelikle standart veri tabanı dili olan
SQL’i iyi bilmek gerekiyor. Bunu sağlamak için dersin ilk dört bölümü SQL’e ayrılmıştır.
Kalan bölümlerde ise PL/SQL ile veri tabanı programlaması işlenmektedir.

VERİ TABANI SİSTEMLERİNE VE SQL DİLİNE


GİRİŞ

Bu bölümde;

• Klasik Dosya Yapıları


• Veri Tabanı Sistemleri
• Veri Tabanı Sistemlerinin Üstünlükleri
• Veri Modelleri
• SQL Yapısal Sorgulama Dillerine Giriş

anlatılmaktadır.

Bölüm Hedefi
Bu bölümde veri tabanı sistemlerine kısa bir giriş
yapılarak, SQL yapısal programlama dilinin esasları
üzerinde durulacak ve aşağıda sıralanan konular
incelenecektir:

• Klasik dosya yapıları


• Veri tabanı sistemleri
• Veri tabanı sistemlerinin üstünlükleri
• SQL sorgulama diline giriş
• SELECT deyiminin temel yapısı
• Aritmetik ifadelerin sorgularda kullanımı
• Çift satırların denetlenmesi

2
• Karşılaştırma işleçleri
• Mantıksal işleçlerin kullanımı
• İşleçlerin işlem sırası

• Verinin sıralanması

1.1 Klasik Dosya Yapıları


Bilgisayarların ilk ortaya çıktığından bu yana hem donanım hem de yazılım alanında pek
çok değişim ortaya çıkmıştır. Doğal olarak bu değişim, kuruluşların ve kişilerin
gereksinimlerine daha iyi cevap verebilmek amacıyla ortaya çıkmaktadır. Pek çok
kuruluşta eskiye oranla çok daha fazla veri üretildiğinden, geleneksel veri saklama ve
işleme tekniklerinin yetersiz kaldığı gözlemlenmiştir. Veri saklama birimlerinde depolanan
veri topluluklarına “dosya” (file) denir.

1.1.1 Kayıt ve Alan


Dosyalar kendi içinde kayıtlara bölünmüştür. Bir sınıftaki öğrenci listesini göz önüne
alalım. Bu liste çok sayıda veri içerebilir. O halde, listenin ana bellekte tutulması söz
konusu olamaz. Ana bellekte tutulduğu takdirde, bilgisayarın kapatılması durumunda bu
bilgiler yok olacaktır. O halde bu verilerin kalıcı bir ortamda, örneğin sabit disk üzerinde
yer alması gerekecektir. Disk üzerinde tutulan bu bilgiler, yeni öğrenci eklendiğinde
büyüyecek veya çıkarıldığında küçülecektir. Ayrıca zaman zaman içeriği değişecektir. Bu
listedeki her bir öğrenci bilgisi bir mantıksal kayıt oluşturur. Her kayıt da farklı bilgiler
içerebilir. Örneğin; öğrencinin adı, baba adı, doğduğu yer vb gibi bilgileri içerebilir.
Sayılan bu bilgilerin herbirine alan (field) adını veriyoruz.

3
1.1.2 Sıralı Dosyalar
Klasik bilgisayar dosyaları birbirinden bağımsız; muhasebe, stok, pazarlama, üretim ve
diğer uygulamalarda kullanılmak üzere hazırlanır. Bu dosyalar, sıralı ya da doğrudan
erişim yöntemleri kullanılarak işlenir. Sıralı erişimde, dosyanın tüm kayıtları tek tek
taranarak istenilen kayıtlara ulaşılır. Doğrudan erişim yönteminde ise, kayıtlar tek tek
sırayla okutulmaz, istenilen kayıda doğrudan erişerek işlenir.

Sıralı dosyalar, bir başka deyişle ardışık dosyalar, içerdiği kayıtlara birinci kayıttan
başlamak üzere sırayla erişim yapmak üzere tasarlanmış dosyalardır. Bu tür dosyaların
kayıtlarına ardışık olarak erişilebilmesine karşılık, kayıtlar fiziksel olarak ardışık
olmayabilir. Sıralı dosyaların herbir kayıtına ardışık olarak erişilmesi bazı durumlarda
yararlı olmasına rağmen, bazı uygulamalarda sorunlar yaratır.

Örneğin; okuldaki tüm öğrencilerin tümü listelenecek ise, kayıtlara peşpeşe erişim söz
konusudur. Bu durumda dosyanın sıralı olarak tasarlanmış olması sorun yaratmaz. Ancak
sadece birkaç öğrencinin listelenmesi isteniliyorsa, tüm öğrencilerin okunarak bu listenin
elde edilmesi uygun bir yöntem olmayacaktır. Söz konusu öğrencilere doğrudan erişilmesi
en uygun yoldur.

1.1.3 İndeksli Dosyalar


Sıralı dosyalar konusunda belirtilen gereksinime karşılık vermek amacıyla doğrudan
erişimli dosyalar kullanılır. Bu tür dosyalarda, her bir arama işlemi dosyanın başından
itibaren yapılmaz. Belirlenen kayıtlara doğrudan erişilerek üzerinde işlem yapılır.

4
Doğrudan erişimli dosyaların en tanınmışı, indeksli dosyalar olarak bilinir. İndeksli
dosyalar veya bir başka deyişle indeks sıralı dosyalar, veri dosyasından ayrı olarak bir
indeks dosyasının oluşturulması ile birlikte hazırlanır. Bir dosya için oluşturulan indeks;
söz konusu dosyanın anahtarları ile bu anahtarların disk üzerinde bulunduğu adresi içerir.
Anahtar alan, erişimde kulanılmak üzere seçilen alan olarak değerlendirilir.

Örneğin; öğrenci dosyasında, öğrenci numarasını içeren alanının indeks alanı olarak
tasarlandığını varsayalım. Herhangi bir öğrencinin bilgilerine ulaşmak söz konusu
olduğunda; bu numara önce indeks üzerinde aranılarak bulunur ve söz konusu kayıda
ilişkin adres bilgisi elde edilerek, bu adrese doğrudan erişilir.

1.1.4 Hesaba Dayalı Dosyalar


Bir diğer doğrudan erişimli dosya türü hesaba dayalı dosyalar (hashed files) olarak bilinir.
Bu tür dosyalar, indeksli dosyalar gibi ayrı bir indeksin tutulmasını gerektirmez. Dosyanın
herhangi bir kaydına doğrudan doğruya erişebilmek için bir hesaplama algoritması
kullanır.

1.2 Veri Tabanı Sistemleri


Karmaşık dosya yapıları ve çok sayıda dosya arası ilişki ve kullanıcıların dosyalara erişimi
söz konusu olduğunda, geleneksel dosya sisteminin yetersiz kaldığı görülmüştür. Bu
sorunu çözmek üzere, veriyi saklama ve veriye erişim konusunda yeni yazılım
teknolojilerine yönelme başlamış ve Veri Tabanı Yönetim Sistemleri (VTYS) yaklaşımı
ortaya çıkmıştır.

5
Veri Tabanı Yönetim Sistemleri (VTYS) yaklaşımında veri girişi ve depolanması, veriye
erişen uygulama programlarından bağımsızdır. Klasik dosya kullanımında ise, kayıt
desenleri ve dosya yapılarında ortaya çıkabilecek en ufak bir değişiklik bile uygulama
programlarının değişmesine ve yeniden derlenmesine neden olmaktadır.

Veri tabanı sistemleri bilgisayar sistemlerinin önemli bir bileşeni olarak değerlendirilir.
Veri tabanı yönetim sistemleri (VTYS), birbirleriyle ilişkili veri ve programlar
topluluğundan oluşmaktadır. Veri topluluğu bir “veri tabanı” olarak değerlendirilir. Veri
tabanı bir kuruluşa ilişkin bilgilerin yer aldığı ortamdır. Veri tabanı sistemleri, veri
kümelerinin düzenli biçimde tutulduğu ve bu verilerin çeşitli yazılımlar aracılığıyla
yönetildiği ortamlardır.

1.3 Veri Tabanı Sistemlerinin Üstünlükleri


Veri tabanı kullanımı, geleneksel dosya kullanımına göre birçok yönden üstünlük
sağlamaktadır.

6
7
8
1.4 Veri Modelleri
Veri Tabanı Yönetim Sistemleri belirli bir veri modeline dayanır. Bir veri tabanı yapısının
temelini veri modeli kavramı oluşturmaktadır. Veriyi mantıksal düzeyde düzenlemek için;
kullanılan kavramlar, yapılar ve işlemler topluluğuna “Veri Modeli” denir.

Şu ana dek birçok veri modeli geliştirilmiştir. Başlıca veri modelleri yandaki animasyonda
yer almaktadır.

Sayılan bu veri modellerinin ilk ikisi şu anda kullanılmamaktadır. En yaygın kullanılanı ise,
İlişkisel Veri Modelidir. Günümüzde kullanılan VTYS’lerin hemen hemen tümü ilişkisel veri
modeline dayalıdır. Son zamanlarda ortaya çıkan Nesneye Yönelik Veri Modeli, İlişkisel
Veri Modeli ile birlikte bazı VTYS’lerde kullanılmaktadır.

Veri Modellerini tekrar görmek için TEKRAR düğmesine tıklayınız

1.5 SQL Yapısal Sorgulama Diline Giriş


Veri tabanı sistemlerinin oluşturulması ve bu veri tabanı üzerinde çeşitli işlemlerin
yapılması söz konusu olacaktır. Örneğin veri tabanı tablolarının yaratılması, bu tablolara
kayıt eklenmesi, kayıtların güncellenmesi, kayıtların sorgulanması ve bunun gibi
işlemlerin yerine getirilmesi gerekecektir. Sayılan bu tür işlemleri yerine getirmek için
ilişkisel veri tabanı sistemlerinde SQL yapısal sorgulama dili olanakları kullanılır.

9
1.5.1 Sorgulama İşlemleri
SQL'de sorgulama işlemleri, SELECT deyimi yardımıyla yerine getirilir. SELECT deyimi
temel olarak üç farklı işlemi yerine getirmek için kullanılır:

1.5.1.1 SELECT Deyiminin Yapısı


SELECT deyimi en basit biçimde şu şekilde ifade edilmektedir;

SELECT [DISTINCT] { * |
sütun, ....}
FROM tablo;

Tanım içinde bazı SQL anahtar kelimelerine yer verilmektedir. Bu anahtar kelimeler, SQL
'in kendi özel kelimeleridir ve aynen bu şekilde ifade edilmelidir.

SELECT SQL'in sorgulama deyimidir.


Hangi tablonun sorgulanacağını ifade
FROM
eder.

10
Çift kayıtları önleyen anahtar
DISTINCT
kelimedir.

Tanımdaki her bir işaretin veya farklı gösterimin hangi anlama geldiğini aşağıdaki
tablodan görebilirsiniz.

Kullanılması zorunlu olmayan SQL sözcükleri, bu


[] işaretler arasında tanımlanır.

Altı çizili ve italik olan bu ifadeler, kullanıcı tarafından


verilen isimleri ifade etmektedir. Bunlar SQL sözcüğü
değildir.

Bu biçimde gösterilen ifadeler, birden fazla seçeneğin


varlığını ve bu seçeneklerden birinin mutlaka seçilmesi
{..|.. } gerektiğini ifade eder. Seçenekler birbirlerinden |
işareti ile ayrılmaktadır.

* Tek bir sütunu değil, tüm sütunları ifade eder.

1.5.1.2 SELECT Yazım Kuralları


SQL deyimleri düzenlenirken bazı kuralları ve önerileri göz önünde tutmak
gerekmektedir. Aksi takdirde sorgu hata verir ve çalışmaz.

SQL sorgu yazım kurallarını aşağıdaki animasyonu inceleyerek görebilirsiniz.

11
1.5.1.3 Tablonun Tüm Satırlarını Seçmek
Bir tablonun tüm sütunlarını seçmek söz konusu ise, SELECT deyimi içinde sütun isimleri
yerine; * işareti kullanılır.

Örnek

BÖLÜM isimli tablonun sütunları şunlardır;

Sütun adı Açıklama


Bölüm_no Bölüm numarasıdır.
Bölüm_adı Bölümün adıdır.

12
Bölümün bulunduğu
Konumu
yerin adıdır.

Bu tablonun içerdiği tüm verileri görüntülemek istiyoruz. Bunun için aşağıda belirtilen
SELECT deyimi düzenlenir:

SELECT * FROM BÖLÜM;

Bu deyimi, daha izlenebilir olmasını sağlamak için şu şekilde de yazabiliriz;

SELECT * FROM
BÖLÜM;

Sorgunun nasıl çalıştığını aşağıda görebilirsiniz.

! Sorguyu çalıştırmak için "Çalıştır" düğmesine tıklayınız.

1.5.1.4 Belirli Sütunların Seçilmesi


Tablo içinde belirlenen sütunların elde edilmesi söz konusu ise, SELECT deyimi içinde bu
sütun isimlerine yer verilir. Sütun isimleri virgüllerle birbirlerinden ayrılır.

13
Örnek

BÖLÜM tablosunun sadece bölüm numaralarını ve bölüm isimlerini içeren sütunlarını,


yani BÖLÜM_NO ve BÖLÜM_ADI sütunlarını seçerek görüntülemek istiyoruz.
Amacımıza uygun SELECT deyimi şu şekilde düzenlenebilir;

SELECT BÖLÜM_NO, BÖLÜM_ADI


FROM BÖLÜM;

Sütun isimleri, tablo isimleriyle birlikte ifade edilebilir. Özellikle


birden fazla tablo varsa bu yola başvurulur. Bunun için, tablo
ismi her bir alanın başına eklenir ve araya bir nokta işareti
konur.

SELECT BÖLÜM.BÖLÜM_NO, BÖLÜM.BÖLÜM_ADI


FROM BÖLÜM;

Sorgunun nasıl çalıştığını aşağıda görebilirsiniz.

! Sorguyu çalıştırmak için "Çalıştır" düğmesine tıklayınız.

14
1.5.2 Aritmetik İfadeler
Aritmetik ifadeler; sütun isimleri, sabit sayısal değerler ve aritmetik işleçlerden oluşur.

Örneğin, bir tablonun ÜCRET isimli sütunundaki sayısal değeri 12 ile çarpmak için,

ÜCRET*12

biçiminde bir ifade tanımlanabilir. SELECT deyimi içinde bir ifade tanımlandığında, bu
ifade ayrı bir sütun biçiminde yaratılmış olacaktır.

Örnek

PERSONEL tablosunun PERSONEL ve ÜCRET isimli iki sütunu listelenecektir. Ayrıca


ÜCRET sütununun içerdiği değere; 1500 değeri eklenerek (yani ücretlere zam yapılıyor)
ayrı bir sütun elde etmek istiyoruz. Amacımıza uygun SELECT deyimi aşağıda görüldüğü
biçimde düzenlenebilir;

SELECT PERSONEL_NO, ADI, ÜCRET+1500


FROM PERSONEL;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız.

15
! Aritmetik İşleçleri ve anlamlarını tekrar görmek için TEKRAR düğmesine
tıklayınız.

1.5.2.1 Aritmetik İfadelerde İşlem Sırası


Aritmetik işleçler, SELECT deyiminin FROM sözcüğü dışında herhangi bir yerinde
kullanılabilir.

Örnek

16
PERSONEL tablosunun, PERSONEL ve ÜCRET isimli iki sütunu listelenecektir. Burada
ÜCRET, aylık ücret rakamını içermektedir. Yıllık ücrete 500 değerini eklemek istiyoruz.
Söz konusu hesaplamayı sağlayan ifade şu şekilde olacaktır;

12*ÜCRET+500

Buna göre * işlecinin önceliğinden dolayı önce 12 ile ÜCRET çarpılacak ve bulunan
değere 500 eklenecektir. Amacımıza uygun SELECT deyimi şu şekilde olabilir;

SELECT PERSONEL_NO, ADI, 12*ÜCRET+500


FROM PERSONEL;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

! Aritmetik İşleçlerin işlem sırasını tekrar görmek için TEKRAR düğmesine tıklayınız.

17
1.5.2.2 Aritmetik İfadelerde Parantezlerin Kullanımı
Parantezler, aritmetik ifadeler içinde diğer tüm işleçlere göre bir önceliğe sahiptir. Önce
parantez içindeki işlemler gerçekleştirilir.

Örnek

Önceki kısımdaki örnekte 12*ÜCRET+500 biçiminde bir tanım yaparak, yıllık ücrete zam
yapmıştık. Bu kez aylık ücrete 500 zam yapmak istiyoruz. Amacımıza uygun ifade şu
şekilde olabilir:

12*(ÜCRET+500)

Bu durumda, ücret sütununun içerdiği değere 500 eklenir ve bulunan değer 12 ile
çarpılır. Amacımıza uygun SELECT deyimi şu şekilde olabilir;

18
SELECT PERSONEL_NO, ADI, 12*(ÜCRET+500)
FROM PERSONEL;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

1.5.2.3 Aritmetik İfadelerde NULL Değerlerin Kullanımı


NULL Değer; var olmayan, atanamayan, bilinmeyen bir değer olarak kabul edilir. NULL
Değer, bir sıfır ya da boşluk olarak da değerlendirilmez. Eğer bir sütun NULL değerler
içeriyorsa, SELECT deyimi çalıştırıldığında bu değerler boş olarak görüntülenir.

Örnek

19
Eğer bir aritmetik ifade içinde NULL değer içeren bir sütun varsa, ifade ne olursa olsun o
satırlarla ilgili sonuç da NULL olarak elde edilir. KOMİSYON isimli sütunun NULL değerler
içerdiği bilinmektedir. O halde;

SELECT ADI, ÜCRET,KOMİSYON, 12*ÜCRET+KOMİSYON


FROM PERSONEL;

deyimi çalıştırıldığında, tanımlanan aritmetik ifade her satır için NULL değerler
üretecektir. NULL ile yapılan hesaplamalara dikkat ediniz. Örneğin,

12*7000+NULL → NULL

olduğu unutulmamalıdır.

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

1.5.3 Sütunlar İçin Takma İsimler Kullanımı


SELECT deyimi çalıştırıldığında, elde edilen sonuçlar yine sütunlar biçiminde olacaktır.
Tablonun sütun isimleri, SELECT deyiminin çalışması sonucu elde edilen listenin sütun
başlıkları olacaktır.

Bunun yerine, çıktı sütunlarına istenilen başlıklar atanabilir. AS anahtar kelimesi bu


amaçla kullanılır. Eğer takma isim birden fazla kelimeden oluşuyorsa tırnak işaretleri
arasında belirtilebilir.

20
Örnek

PERSONEL tablosunun PERSONEL sütunu için İSİM, ücret sütunu için AYLIK_ÜCRET
takma isimlerini atayacağız. Ayrıca yıllık ücreti hesaplayarak bu sütuna da
YILLIK_ÜCRET takma ismini vermek istiyoruz. Amacımıza uygun SELECT deyimi şu
şekilde olabilir;

SELECT ADI AS İSİM, ÜCRET AS AYLIK_ÜCRET,


12*ÜCRET+KOMİSYON AS YILLIK_ÜCRET
FROM PERSONEL;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

21
1.5.4 Sütun İçeriklerini Birleştirme
Sütunların içerdikleri değerleri, birbiriyle ya da bir başka karakter dizisi ile birleştirerek
yeni değerler elde edilebilir. Birleştirme işleci olarak (||) simgesi kullanılabilir. Bu işlecin
kulllanımı veri tabanlarında farklılık gösterebilir. Örneğin, ORACLE veri tabanında (||); MS
Access veri tabanında ise (&) işleci aynı amaçla kullanılır.

Örnek

Personel adı ve görev bilgisini birleştirerek, iki sütun bilgisi arasına "-" işaretini
yerleştirmek ve tek sütun biçiminde görüntülemek istiyoruz. SELECT deyimini ORACLE
veri tabanı için şu şekilde düzenleyebiliriz;

SELECT ADI || '-' || GÖREVİ AS ADI_GÖREVİ


FROM PERSONEL;

Aynı amaca SELECT deyimini MS Access veri tabanında şu şekilde kullanarak ulaşabiliriz;

SELECT ADI & "-" & GÖREVİ AS ADI_GÖREVİ


FROM PERSONEL;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

22
1.5.5 Aynı Değere Sahip Satırlar
Bir SELECT deyimi çalıştırıldığında, aynı değerlere sahip satırların görüntülenmesi
engellenemez. Örneğin,

SELECT BÖLÜM_NO
FROM PERSONEL;

deyimi çalıştırıldığında, PERSONEL tablosunun BÖLÜM_NO sütunu içerikleri aynen


listelenir. Bu sütunun içerdiği değerlerin çoğu birbirinin aynı olabilir. Eğer tekrarlı
değerlerin sadece bir tanesinin elde edilmesi söz konusu ise, SELECT deyimi DISTINCT
anahtar kelimesi ile birlikte kullanılır.

SELECT DISTINCT BÖLÜM_NO


FROM PERSONEL;

Örnek

23
PERSONEL tablosunun BÖLÜM_NO sütunundaki verileri tekrarlatmadan listelemek
istiyoruz. Bunun için aşağıda belirtilen yol izlenir;

SELECT DISTINCT BÖLÜM_NO


FROM PERSONEL;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

1.5.6 Verinin Sınırlandırılması


Veri tabanından veriyi alma sırasında, satırlara bazı kısıtlamalar koyarak, tablonun tüm
satırları yerine bir kısmı elde edilebilir.

Tablonun belirli kısımlarını seçmek için WHERE sözcüğü kullanılır. Bu sözcük SELECT
deyimi içinde aşağıda gösterildiği biçimde yer alır. WHERE sözcüğü içinde tanımlanan
koşul; sütun içindeki değerleri, literal değerleri, aritmetik ifadeleri veya fonksiyonları
içerebilir.

24
Örnek

PERSONEL tablosu içinde yer alan personel arasında görevi MEMUR olanları seçerek
listelemek istiyoruz. Amacımıza uygun SELECT deyimi şu şekilde düzenlenebilir;

SELECT ADI,GÖREVİ,BÖLÜM_NO
FROM PERSONEL
WHERE GÖREVİ='MEMUR';

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

1.5.6.1 Karşılaştırma İşleçleri


WHERE sözcüğü içinde tanımlanan kısıtlama ifadelerinde, yani koşul ifadelerinde çeşitli
karşılaştırma işleçleri kullanılır.

25
! Karşılaştırma İşleçlerini ve anlamlarını tekrar görmek için 'TEKRAR'
düğmesine tıklayınız.

Örnek

Ücreti 2500'den daha az ya da eşit olan personeli seçerek listelemek istiyoruz. Amacımıza
uyan SELECT deyimi şu şekildedir;

SELECT ADI,GÖREVİ,ÜCRET
FROM PERSONEL
WHERE ÜCRET<=2500;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

26
1.5.6.2 Diğer Karşılaştırma İşleçleri
Şu ana kadar öğrendiğimiz karşılaştırma işleçleri dışında, bazı özel amaçlarla
kullanılabilecek başka karşılaştırma işleçleri de bulunmaktadır. Aşağıdaki etkileşimli
listeden bu işleçleri ve anlamlarını görebilirsiniz.

27
1.5.6.2.1 BETWEEN … AND ... İşleci
Bu işleç; iki değer arasında kalan satırları belirlemek ve bir alt değer ile bir üst değer
arasında kalan değerleri seçmek için kullanılabilir.

Örnek

Ücreti 3000 ile 5000 arasında olan personeli listelemek için SELECT deyimi şu şekilde
kullanılabilir;

SELECT ADI,ÜCRET
FROM PERSONEL
WHERE ÜCRET BETWEEN 3000 AND 5000;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

28
1.5.6.2.2 IN İşleci
Sütun değerlerinin, bir listedeki değerler ile karşılaştırılması söz konusu ise, SELECT
deyimi ile birlikte IN işleci kullanılır. Liste içindeki değerler birbirlerinden virgüllerle
ayrılır. IN işleci herhangi bir veri türü için kullanılabilir. Karakter ve tarih veri türleri,
tırnak işareti arasında yer almalıdır.

IN( liste)

Örnek

Görevi MEMUR veya PAZARLAMACI olan tüm personeli listelemek istiyoruz. Bunun için IN
işlecini kullanabiliriz.

SELECT ADI,GÖREVİ
FROM PERSONEL
WHERE GÖREVİ IN('MEMUR', 'PAZARLAMACI');

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

29
1.5.6.2.3 LIKE İşleci
WHERE sözcüğü ile, bir sütunun değerini tam olarak değil, sadece bir kısmını belirterek
arayabiliriz. Örneğin, adı "A" harfi ile başlayan personeli aramak gibi. Bu tür amaçlar için
LIKE işleci kullanılabilir. Bu operatör ile birlikte, farklı amaçlar için (%) veya (_)
işaretleri kullanılabilir.

Bunlardan (%) işareti, bu işaretten önce ya da sonra gelen karakterler için arama
yapılacağını belirtir. Örneğin, "A" harfi ile başlayanlar, 'A%' biçiminde; "S" harfi ile
bitenler, '%S' biçiminde ifade edilir. (_) işareti ise herhangi bir tek karakteri simgeler.
LIKE ile birlikte kullanılan (%) işareti yerine, MS Access'de (*) işareti kullanılır.

LIKE ( kural)

Örnek

Adı "A" harfi ile başlayan tüm personeli listelemek istiyoruz. Amacımıza uygun SELECT
deyimi şu şekilde düzenlenebilir;

SELECT ADI, GÖREVİ


FROM PERSONEL
WHERE ADI LIKE "A*";

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

30
1.5.6.2.4 IS NULL İşleci
NULL değeri; var olmayan, atanamayan ve bilinmeyen bir değer olduğu için NULL ile ilgili
karşılaştırmalarda (=) işleci kullanılamaz. Bunun yerine, sütun değerlerinin NULL olup
olmadığını denetlemek için IS NULL işleci kullanılır.

Eğer söz konusu tabloda NULL olmayan alanlar


aranacak ise, bu kez IS NOT NULL işlecine
başvurmak gerekecektir.

Örnek

PERSONEL tablosu içinde komisyon alan personeli listelemek istiyoruz. Komisyon


almayan personelin bu sütunları NULL değerler içerdiği için, NULL olmayan değerleri
seçerek amacımıza ulaşıyoruz.

SELECT ADI, GÖREVİ,KOMİSYON


FROM PERSONEL
WHERE KOMİSYON IS NOT NULL;

31
Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

1.5.6.3 Mantıksal İşleçler


Koşulları içeren karşılaştırma işlemlerinde mantıksal işleçlere de yer verilebilir. Bu
işleçlerden; AND ve OR iki koşulu birlikte değerlendirmek üzere kullanılırlar.

32
1.5.6.3.1 AND İşleci
AND işleci; iki koşulun yandaki doğruluk değeri tablosuna göre TRUE veya FALSE
değerinin döndürülmesini sağlar. Eğer, her iki koşulun doğruluk değeri TRUE ise istenen
seçme işlemi gerçekleşir.

Örnek

Ücreti 2000'e eşit veya daha büyük ve işi MEMUR olan personeli listelemek istiyoruz.
Amacımıza uygun SELECT deyimi, şu şekilde olabilir;

SELECT ADI, GÖREVİ, ÜCRET


FROM PERSONEL
WHERE ÜCRET>=2000
AND GÖREVİ='MEMUR';

Eğer belirli bir personelin ücreti 2000'e eşit veya daha fazla ise; ÜCRET>=2000 koşulu
doğru olacaktır. Yani TRUE değerini döndürür. Aynı personelin görevi memur ise yani,
GÖREVİ='MEMUR' koşulu doğru ise, bu koşul da TRUE değerini döndürür. Böylece her iki
koşul için TRUE değerlerine sahip olan personel isimleri listelenir.

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

33
1.5.6.3.2 OR İşleci
OR işleci; iki koşulun yandaki doğruluk değeri tablosuna göre TRUE veya FALSE
değerinin döndürülmesini sağlar. Eğer, her iki koşulun doğruluk değeri TRUE ise istenen
seçme işlemi gerçekleşir.

OR İşleci Doğruluk Tablosu

Örnek

Komisyon alan veya görevi MEMUR olan personeli listelemek istiyoruz. Amacımıza uygun
SELECT deyimi şu şekildedir;

SELECT ADI, GÖREVİ, ÜCRET


FROM PERSONEL
WHERE KOMİSYON IS NOT NULL
OR GÖREVİ='MEMUR';

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

34
1.5.6.3.3 NOT İşleci
NOT işleci; bir koşulun doğruluk değeri TRUE ise FALSE; FALSE ise TRUE değerini
döndürmesini sağlar. Bu işleç IN, LIKE, NULL ve BETWEEN işleçleriyle birlikte
kullanılabilir.

NOT İşleci Doğruluk Tablosu

Örnek

Mesleği MEMUR, ŞEF veya PAZARLAMACI olmayan personeli listelemek için aşağıdaki
SELECT deyimi kullanılabilir;

SELECT ADI, GÖREVİ


FROM PERSONEL
WHERE GÖREVİ NOT IN('MEMUR', 'ŞEF', 'PAZARLAMACI');

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

35
1.5.6.3.4 İşleçlerin İşlem Sırası
WHERE sözcüğü içinde yer alan işleçler, yanda gösterilen sıraya göre işlem görürler. Bu
işleçlerin dışında, parantezler de kullanılabilir. Parantezler tüm işleçlere göre bir önceliğe
sahiptir. Yani öncelikle parantez içindeki işlemler yapılır, ardından da yandaki tabloya
göre işlem sırası uygulanır.

! İşleçlerin işlem sıralarını tekrar görmek için 'TEKRAR'


düğmesine tıklayınız.

Örnek 1

Aşağıdaki SELECT deyimini göz önüne alalım:

SELECT ADI, GÖREVİ,ÜCRET


FROM PERSONEL

36
WHERE GÖREVİ='MEMUR'
OR GÖREVİ='ŞEF'
AND ÜCRET>3000;

İşleçlerin öncelik sırasını göz önüne alarak değerlendirme yapmamız gerekiyor. AND
işleci OR dan daha öncelikli olduğu için, AND işlecini ilgilendiren koşulu öncelikle
değerlendirmemiz gerekiyor. Ardından geriye kalan koşulu göz önüne alıyoruz. O halde
aşağıda belirtildiği biçimde iki koşuldan söz edilebilir;

1) Görevi ŞEF olanlar ve ücreti 3000'den fazla olanlar


2) Görevi MEMUR olanlar

Bu iki koşulu öncelik sıralarını göz önüne alarak birleştirirsek, şöyle bir seçme işlemiyle
karşılaşırız;

"Görevi ŞEF olanlar ve ücreti 3000'den fazla olanlar veya görevi MEMUR olanların seçimi"

Örnek 2

Görevi; ŞEF veya MEMUR olanlar ve ücreti 3000'den fazla olanların seçimini yapacak
SELECT deyimini yazınız.

SELECT ADI, GÖREVİ,ÜCRET


FROM PERSONEL
WHERE (GÖREVİ='MEMUR'
OR GÖREVİ='ŞEF')
AND ÜCRET>3000;

Parantezlerin öncelik sırasına sahip olduğunu unutmayınız.

1.5.6.4 Sıralama İşlemleri


Tabloların satırlarının, herhangi bir sütuna göre sıralı olarak elde edilmesi söz konusu ise,
SELECT deyimi ORDER BY sözcükleri ile birlikte kullanılır. Sıralama sözcükleri de dahil
olmak üzere SELECT deyimi şu şekilde tanımlanır;

SELECT [DISTINCT] { * | sütun, ....}


FROM tablo
[WHERE koşul [ORDER BY {sütun,
ifade} [ASC | DESC] ];

37
Örnek 1

Personeli işe giriş tarihine göre sıralamak istiyoruz. Bunun için SELECT deyimi şu şekilde
düzenlenebilir;

SELECT ADI, GÖREVİ, GİRİŞ_TARİHİ


FROM PERSONEL
ORDER BY GİRİŞ_TARİHİ;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

38
Örnek 2

Bu kez personeli ücretine göre her bölüm içinde sıralamak istiyoruz. Bu durumda,
bölümleri ve ücretleri birlikte sıralamız söz konusudur. SELECT deyimi şu şekilde
düzenlenebilir;

SELECT BÖLÜM_NO, ADI, ÜCRET


FROM PERSONEL
ORDER BY BÖLÜM_NO, ÜCRET DESC;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

39
40
41
42
43
44
45
46
FONKSİYONLARIN KULLANIMI VE
GRUPLAMA İŞLEMLERİ

Bu bölümde;

• Fonksiyon
• SQL Fonksiyonları
• Tek Satır Fonksiyonları
• İç İçe Fonksiyonlar
• Grup Fonksiyonları
• Gruplama İşlemleri

anlatılmaktadır.

Bölüm Hedefi
Bu bölümde aşağıda belirtilen konular ele alınarak
incelenecektir:

• Fonksiyon nedir ?
• SQL fonksiyonları
• İç içe fonksiyonlar
• Grup fonksiyonları

• Gruplama işlemleri

2.1. Fonksiyon Nedir ?


Fonksiyonlar veya bir başka deyişle işlevler, SQL'e bazı güçlü özellikler katan olanaklar
olarak değerlendirilir. SQL fonksiyonları, aynen programlama dillerinde olduğu gibi,
kullanıcıya bazı özel işlemleri ve hesaplamaları otomatik olarak sağlar. Bir fonksiyon;
çeşitli argümanları girdi olarak alıp bir sonuç üreten hazır bileşenlerdir. Kullanıcının,
fonksiyonun adını ve gerekli argümanları tanımlaması yeterlidir. Bu bilgilere dayalı olarak
fonksiyon, bir sonuç döndürür (üretir).

47
2.2 SQL Fonksiyonları
SQL fonksiyonları iki ana grup altında incelenmektedir:

48
Tek satır fonksiyonları, tablonun bir satırı için uygulanır ve her satır için bir sonuç üretilir.
Çoklu satır fonksiyonları ise, bir grup satıra uygulanır ve sonuç buna göre elde edilir.

Burada anlatılan SQL standart ANSI SQL 'dir. Ancak bazı fonksiyonları tüm veri
tabanlarının desteklemediğini göreceksiniz. ANSI SQL'in tüm özelliklerini
barındıran ORACLE veri tabanı üzerinde çalıştığımızı varsayarak, fonksiyonları
ona göre anlatacağız.

2.3 Tek Satır Fonksiyonları


Tek satır fonksiyonları, tablonun her bir satırına uygulanan fonksiyonlardır. Tek satır
fonksiyonlarının birçok türü bulunmaktadır.

Bu derste, aksi söylenmedikçe "fonksiyon" sözcüğü ile tek satır fonksiyonlarından söz
edildiği anlaşılacaktır. Tek satır fonksiyonlarını aşağıda belirtildiği biçimde tanımlıyoruz;

49
fonksiyon Herhangi bir SQL fonksiyonunu
simgeler. Örneğin LOWER bir
fonksiyon ismidir. Bu ismi
sütun
değiştiremeyiz.
ifade Herhangi bir tabloya ilişkin sütun adı
argümanlar Herhangi bir karakter dizisi ya da
hesaplama ifadesi
Fonksiyonla birlikte kullanılabilecek
argümanlar

2.3.1 Karakter Fonksiyonları


Karakter fonksiyonları; karakter verileri girdi olarak alan, karakter ya da sayısal değerler
döndürebilen fonksiyonlardır.

Bu fonksiyonların en çok kullanılanlarını şu şekilde sıralayabiliriz;

Alfabetik karakterleri küçük


harflere dönüştür.
Alfabetik karakterleri büyük
harflere dönüştür.
Alfabetik karakterlerin
birincisini büyük harfe;
diğerlerini ise küçük harfe
çevirir.
Katarları (karakter dizileri)
birleştirmek için kullanılır.
(||) ile aynı görevi yapar.
Bir katarın m.
pozisyonundan itibaren n
karakterinden yeni bir katar
oluşturur.

50
Bir sütunun ya da katarın
içerdiği karakter sayısını
döndürür.

Bu eğitimde bahsedilen fonksiyonlar, ORACLE veri tabanı için verilmiştir. Bu fonksiyonlar,


bazı veri tabanlarında farklılık gösterebilir. Örneğin; MS Access'de bu fonksiyonların
bazıları farklı biçimdedir.

2.3.1.1 LOWER() ve UPPER() Fonksiyonları


Bu fonksiyonlar, bir karakterin büyük harfe ya da küçük harfe dönüştürülmesi söz konusu
olduğunda kullanılabilir.

a. LOWER() Fonksiyonu

LOWER() fonksiyonu, bir karakter katarının tüm harflerini küçük harflere dönüştürür.

Örnek

PERSONEL tablosunda personel isimleri büyük harflerle yazdırılmış olarak yer


almaktadır. Bu isimleri küçük harflerle görüntülemek için SELECT deyimi şu şekilde
düzenlenebilir;

SELECT LCASE(ADI) AS İSİMLER


FROM PERSONEL
WHERE BÖLÜM_NO=10 OR GÖREVİ='PAZARLAMACI'

Yukarıdaki SELECT deyimi MS Access


veri tabanı için düzenlenmiştir. MS
Access veri tabanında LOWER()
fonksiyonu yerine LCASE()
fonksiyonu kullanılmaktadır.

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

51
b. UPPER () Fonksiyonu

UPPER() fonksiyonu, bir karakter katarındaki tüm harfleri büyük harflere çevirir.

2.3.1.2 LENGTH() Fonksiyonu


Bir karakter katarın kaç karakterden oluştuğunu veya uzunluğunu bulmak amacıyla
ORACLE veri tabanında LENGTH(); MS Access veri tabanında LEN() fonksiyonu kullanılır.
Lenght() fonksiyonu, bir sayısal değer döndürür.

52
Örnek

Personel isimlerinin kaç karakterden oluştuğunu bulmak istiyoruz. Bu amaçla SELECT


deyimi şu şekilde kullanılabilir;

SELECT ADI,LEN(ADI) AS İSİMLER


FROM PERSONEL;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

2.3.2 Sayısal Fonksiyonlar


Sayısal veriler üzerinde çeşitli işlemleri gerçekleştirmek üzere özel fonksiyonlar
bulunmaktadır. Sayısal fonksiyonlar, sayısal veriler alır ve yine sayısal sonuçlar üretirler.

53
Bu fonksiyonların en çok kullanılanlarını şu şekilde sıralayabiliriz:

Sayısal değeri yuvarlatmak


amacıyla kullanılır.
Sayısal değeri belirtilen ondalığa
göre budamak (kesmek)
amacıyla kullanılır.
İki sayısal değerin, m ve n 'nin
birbirine bölümünden elde edilen
kalanı döndürür.

7.3.2.1 ROUND() Fonksiyonu


ROUND() fonksiyonu, bir sütun değerinin veya bir ifadenin içerdiği sayısal değerin
yuvarlatılması amacıyla kullanılır. Yuvarlatma işlemi, bir n ondalık hanesine göre yapılır.

54
Eğer n sıfır ise veya fonksiyon içinde belirtilmemiş ise, yuvarlatma sonunda elde edilecek
tamsayının ondalık hanesi olmayacaktır. ROUND() fonksiyonu şu şekilde tanımlanır;

Örnek

PERSONEL tablosunun ÜCRET sütunundaki bilgiler aylık ücretleri kapsamaktadır. Görevi


MEMUR olanlar için, aylık ücretleri 30'a bölerek günlük ücretleri bulmak ve sonucu 2
ondalık haneye göre yuvarlatmak istiyoruz. Amacımıza uygun SELECT deyimi şu şekilde
olacaktır;

SELECT ADI,ÜCRET AS AYLIK,


ROUND(ÜCRET/30,2) AS GÜNLÜK
FROM PERSONEL
WHERE GÖREVİ='MEMUR';

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

55
2.3.3 Tarih Fonksiyonları
Tarih işlemlerinde kullanılan bazı tarih fonksiyonlarından söz edilebilir. Bu fonksiyonların
en çok kullanılanlarından biri SYSDATE fonksiyonudur. Bu fonksiyonun herhangi bir
argümanı bulunmamaktadır. O andaki tarih ve zaman bilgisini elde etmek amacıyla
kullanılır. Diğer tarih fonksiyonlarını aşağıdaki tablo üzerinde görebilirsiniz;

Fonksiyon İşlevi
İki tarih arasında kaç aylık bir
süre olduğunu saptar.
Belirli bir tarih bilgisine n ay
ilave edildiğinde hangi tarihe
ulaşılacağını belirler.
Haftanın belirli bir gününün,
bir sonra hangi tarihe karşılık
geldiğini bulmak için kullanılır.
Belirlenen tarihe ilişkin ayın
son gününü bulmak için
kullanılır.

Örnek 1

Personelin işe giriş tarihinden bu zamana kadar olan süreyi ay olarak hesaplatmak
istiyoruz. Amacımıza uygun SELECT deyimi şu şekilde olabilir;

56
SELECT ADI, GİRİŞ_TAR,
MONTHS_BETWEEN (SYSDATE,GİRİŞ_TAR) AS AY
FROM PERSONEL;

Örnek 2

İşe giriş süresi 200 aydan daha az olan personeli listelemek için şu şekilde bir sorgu
yapılabilir;

SELECT ADI,GİRİŞ_TAR,
MONTHS_BETWEEN(SYSDATE,GİRİŞ_TAR) AS AY
FROM PERSONEL
WHERE MONTHS_BETWEEN(SYSDATE,GİRİŞ_TAR)<200;

Örnek 3

Personelin işe giriş tarihinden 6 ay sonrasının hangi tarihe karşılık geldiğini hesaplayan
bir sorgu şu şekilde oluşturulabilir;

SELECT ADI, GİRİŞ_TAR, ADD_MONTHS (GİRİŞ_TAR,6)


FROM PERSONEL;

Örnek 4

Personelin işe giriş tarihlerini göz önüne alarak her bir tarihin ait olduğu ayın en son
gününü belirleyen sorgu ifadesi şu şekilde olabilir;

SELECT ADI, GİRİŞ_TAR, LAST_DAY(GİRİŞ_TAR)


FROM PERSONEL;

2.3.4 Dönüştürme Fonksiyonları


Karakter, sayısal ve tarih verilerinin birbirlerine dönüştürülmesi ve özellikle biçimlendirme
işlemlerinde çeşitli fonksiyonlardan yararlanılır. Bu fonksiyonları aşağıdaki tabloda
görebilirsiniz;

Fonksiyon İşlevi
Tarih veya sayısal bilginin
istenildiği gibi biçimlendirilerek
karakter dizisine dönüştürülmesini
sağlar.
Bir karakter katarının içerdiği
sayısal değerleri istenildiği gibi
biçimlendirilerek sayısal veri türüne
dönüştürmek için kullanılır.
Bir karakter katarının içerdiği tarih
verilerini istenildiği gibi
biçimlendirilerek tarih veri türüne
dönüştürmek için kullanılır.

2.3.4.1 TO_CHAR Fonksiyonu

57
Bu fonksiyon, tarih veya sayısal bilginin istenildiği gibi biçimlendirilerek karakter dizisine
dönüştürülmesini sağlar. İki farklı uygulama alanı bulunmaktadır. Eğer tarih bilgisini
karakter dizisine, yani bir katara dönüştürmek söz konusu ise;

tanımı uygulanır.

Eğer, bir sayısal değerin karakter katarına dönüştürülmesi isteniyorsa,

tanımı kullanılır. Aşağıdaki canlandırmada TO_CHAR fonksiyonu; bir sayısal değeri


biçimlendirerek karakter dizisine çeviriyor.

Tarihle ilgili biçimlendirme ifadesi; bazı biçimlendirme elemanlarından ve kurallardan


oluşur. Biçimlendirme ifadesi, tek tırnaklar arasında yazılır ve büyük küçük harf ayrımına
karşı duyarlıdır. Tarih ile ilgili biçimlendirme ifadelerinde aşağıdaki tanımlardan
yararlanılır;

Eleman Anlamı
YYYY Dört haneli yıl bilgisi. Örneğin; 2002
YEAR Yılın rakamlarla değil, okunduğu gibi yazılması
MM İki haneli ay bilgisi
MONTH Ayın tam adı
DD İki haneli gün bilgisi
DY Haftanın günü. Üç karakterden oluşur.
DAY Günün tam adı

58
Zamanla ilgili biçimlendirme ifadeleri ise aşağıdaki elemanlardan oluşabilir;

Eleman Anlamı
AM,PM Meridyen göstergesi
HH Günün saati
MI Dakika bilgisi
SS Saniye bilgisi

Sayısal değerleri kullanan TO_CHAR() fonksiyonu, aşağıdaki tabloda yer alan


biçimlendirme elemanlarını kullanabilir;

Eleman Anlamı
9 Sayısal değeri ifade eder.
0 Sıfır değerini ifade eder.
$ Dolar işaretini yerleştirir.
L Yerel para işaretini yerleştirir.
. Ondalık hanesini gösterir.
, Binler hanesini gösterir.

Örnek 1

Personelin işe giriş tarihlerini MM/YY biçiminde elde etmek için şu şekilde bir sorgu
düzenlenebilir;

SELECT ADI,TO_CHAR(GİRİŞ_TAR,'MM/YY')
FROM PERSONEL;

Örnek 2

Personel ücretlerini, binler hanesinden ayırarak elde etmek istiyoruz. Ayrıca ücret
rakamının sol tarafına ($) işaretini yerleştireceğiz. Amacımıza uygun sorgu şu şekilde
düzenlenebilir;

SELECT ADI,TO_CHAR(ÜCRET,'$99,999')
FROM PERSONEL;

2.3.4.2 TO_NUMBER Fonksiyonu


Karakter alan olarak tanımlanmış bir sütunun içerdiği sayısal değerleri, sayısal veri türüne
dönüştürmek için TO_NUMBER() fonksiyonu kullanılır. Bu fonksiyon şu şekilde
tanımlanır;

Aşağıdaki canlandırmada, TO_NUMBER() fonksiyonu bir karakter katarı girdisini sayısal


veri türüne çeviriyor.

59
Biçimlendirme ifadesi, TO_CHAR() fonksiyonunda olduğu gibi, aşağıda yer alan işaretler
kullanılarak düzenlenir;

Eleman Anlamı
9 Sayısal değeri ifade eder.
0 Sıfır değerini ifade eder.
$ Dolar işaretini yerleştirir.
L Yerel para işaretini yerleştirir.
. Ondalık hanesini gösterir.
, Binler hanesini gösterir

2.3.4.3 TO_DATE Fonksiyonu


Karakter dizisi olarak saklanan ifadeleri tarih bilgisine çevirmek söz konusu olduğunda
TO_DATE() fonksiyonuna başvurulur. Bu fonksiyon şu şekilde tanımlanır;

Biçimlendirme ifadesi içinde, TO_CHAR() fonksiyonu için geçerli olan biçimlendirme


ifadeleri kullanılabilir.

Aşağıdaki canlandırma TO_DATE() fonksiyonun çalışma prensibini anlatmaktadır.

60
Örnek

İşe giriş tarihlerine göre PERSONEL tablosunu sorgulayacağız. Arama ifadesi "Ocak 1,
1980" biçiminde olabilir. Bu ifadeyi SELECT deyiminin yorumlayabileceği bir biçime
dönüştürmek gerekiyor. Amacımıza uygun SELECT deyimi şu şekilde olabilir;

SELECT ADI, GİRİŞ_TAR


FROM PERSONEL
WHERE GİRİŞ_TAR=TO_DATE('OCAK 1,1980',MONTH DD, YYYY');

2.3.5 Genel Fonksiyonlar


Bu bölümde daha önce gördüğümüz fonksiyonların dışında SQL'in birçok fonksiyonu
bulunmaktadır. SQL fonksiyonlarının bir kısmını sonraki bölümde gruplama fonksiyonları
olarak ele alarak inceleyeceğiz. Ancak burada SQL'in önemli iki fonksiyonu üzerinde
duracağız. Bu fonksiyonlar, NVL() ve DECODE() fonksiyonlarıdır.

! Fonksiyonların görevlerini öğrenmek için, fonksiyon isimleri yazılı düğmelere tıklayınız.

2.3.5.1 NVL() Fonksiyonu


Bir sütunun içeriği NULL ise, SELECT deyimi ile yapılan sorgularda bu içerik boş olarak
görüntüleniyordu. Bunun yerine, NULL değer ile karşılaşıldığında, bir başka ifadenin
görüntülenmesi sağlanabilir. NVL() fonksiyonu, NULL değerler yerine bir başka değerin
yer almasını sağlar. NVL() fonksiyonu şu şekilde tanımlanır;

61
! NVL() fonksiyonunun EVET ve HAYIR durumlarında çalışma şeklini görmek için; EVET ve
HAYIR düğmelerine tıklayınız.

Örnek 1

Yıllık toplam ücretleri hesaplamak istiyoruz. Bunun için; aylık ücret bilgisi, 12 ile
çarpılacak ve bulunan sonuca komisyon miktarı eklenecektir. Ancak pek çok personelin
komisyon bilgisi NULL değerler içermektedir. NULL değerler içeren sütunlar üzerinde
aritmetik işlemler yapamayız. NULL değerler yerine 0 değerini yerleştirerek hesaplamalar
yapılabilir. O halde, NVL() fonksiyonunu kullanmamız söz konusudur. Amacımıza uygun
SELECT deyimi şu şekilde olmalıdır;

SELECT ADI,ÜCRET,KOMİSYON,ÜCRET*12+NVL(KOMİSYON,0)
FROM PERSONEL;

Örnek 2

İşe giriş tarihleri NULL olan personel için '01-01-2002' tarihini işe başladığı tarih olarak
görüntüleyen SELECT deyimi şu şekilde olabilir;

SELECT ADI,GİRİŞ_TAR,NVL(GİRİŞ_TAR,'01-01-2002')
FROM PERSONEL;

62
Örnek 3

Görevi henüz belli olmayan personel için, görev olarak "GÖREVİ BELİRLENMEDİ" mesajını
görüntüleyen SELECT deyimi şu şekilde olabilir;

SELECT ADI, GÖREVİ, NVL(GÖREVİ,'GÖREVİ BELİRLENMEDİ')


FROM PERSONEL;

2.3.5.2 DECODE() Fonksiyonu


Programlama dillerinde kullanılan CASE veya IF..THEN..ELSE denetim deyimlerinin SQL
içinde tam karşılığı olabilecek bir deyim yoktur. Onun yerine, aynı işlevi yerine getirmek
üzere DECODE() fonksiyonundan yararlanılır. Bu fonksiyon şu şekilde tanımlanır;

63
Örnek

Personel arasında görevi; MEMUR olanlara %10, ŞEF olanlara %15, MÜDÜR olanlara
ise, %20 zam yapılacaktır. Diğerlerinde ise herhangi bir değişiklik olmayacaktır. Bu
işlemleri yerine getirmek üzere aşağıdaki SELECT deyimini düzenliyoruz;

SELECT ADI,GÖREVİ,ÜCRET,
DECODE(GÖREVİ,'MEMUR', ÜCRET*1.10,
'ŞEF',ÜCRET*1.15,
'MÜDÜR'ÜCRET*1.20,
ÜCRET) AS "YENİ ÜCRETLER"
FROM PERSONEL;

2.4 İç İçe Fonksiyonlar


Bir SELECT deyimi içinde herhangi bir fonksiyonun nasıl kullanılabildiğini gördük. Bazı
uygulamalarda, bir fonksiyonun içinde bir başka fonksiyona yer vermek gerekebilir.
Örneğin,

DECODE(TRUNC(ücret,0), …)

biçiminde bir tanım yapılabilir. Burada DECODE() fonksiyonu içinde TRUNC()


fonksiyonunun kullanıldığı görülüyor. İç içe fonksiyonlarda, önce iç taraftaki fonksiyon
işlem görür, ardından elde edilen sonuç dıştaki fonksiyon tarafından kullanılır.

! Adımların sonuçlarını görmek için ADIM 1, ADIM 2 ve ADIM 3 düğmelerine tıklayınız.

64
2.5 Grup Fonksiyonları
Tek satır fonksiyonları, tablonun bir satırına uygulanabiliyor ve buna karşılık gelen bir
sonuç satırı elde edilebiliyordu. Bir grup satıra bir fonksiyonun uygulanması söz konusu
ise; "çoklu satır" ya da bir başka deyişle "grup fonksiyonlarından" söz edilir. Grup
fonksiyonları tablonun tüm satırlarına uygulanabildiği gibi, GROUP BY sözcüğü
yardımıyla da alt gruplara uygulanabilir.

Bir tablonun tüm satırları için grup fonksiyonu uygulanacak ise, SELECT deyimi aşağıda
belirtildiği biçimde kullanılır;

65
2.5.1 AVG() Fonksiyonu
Herhangi bir sütunun içerdiği sayısal değerlerin aritmetik ortalamasını hesaplamak
amacıyla; AVG() fonksiyonu kullanılır. Bu fonksiyonun uygulandığı sütunun veri türü
sayısal olmalıdır.

Örnek 1

Personel ücretlerini göz önüne alalım. Ücretlerin ortalamasını bulmak için şöyle bir yol
izlenir;

66
SELECT AVG (ÜCRET) AS ORTALAMA
FROM PERSONEL;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

Örnek 1

Personel ücretlerini göz önüne alalım. Ücretlerin ortalamasını bulmak için şöyle bir yol
izlenir;

SELECT AVG (ÜCRET) AS ORTALAMA


FROM PERSONEL;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

Örnek 2

Personel arasında görevi MEMUR olanların ortalama ücreti aşağıda gösterildiği biçimde
hesaplanabilir;

SELECT AVG (ÜCRET) AS ORTALAMA,


FROM PERSONEL
WHERE GÖREVİ='MEMUR';

67
2.5.2 SUM() Fonksiyonu
Sütunların içerdiği sayısal değerleri toplamak amacıyla SUM() fonksiyonundan
yararlanılır.

Örnek

Tüm personel ücretlerinin toplamını hesaplayan SELECT deyimi aşağıda gösterildiği


biçimde oluşturulabilir;

SELECT SUM(ÜCRET) AS TOPLAM


FROM PERSONEL;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

68
2.6 Gruplama İşlemleri
Bir tablonun satırları gruplara ayrılarak, grup fonksiyonlarının bunlara uygulanması
sağlanabilir. Böyle bir amaçla SELECT deyimi içinde GROUP BY sözcüğünden
yararlanılır.

SELECT sütun, grup fonksiyonu(sütun)


FROM tablo
[WHERE koşul] [GROUP BY sütun]
[ORDER BY sütun];

PERSONEL tablosunda bulunan personel ücretlerini; Bölüm_No'suna göre gruplayıp her


bölümdeki toplam personel harcamalarını bulabiliriz. Bunun için;

SELECT BÖLÜM_NO, SUM(ÜCRET) AS TOPLAM_ÜCRET


FROM PERSONEL
GROUP BY BÖLÜM_NO;

Örnek

PERSONEL tablosunu göz önüne alarak, her bölüm için personel sayısını, ücret toplamını
ve ortalama ücretleri hesaplayan SELECT deyimi şu şekilde oluşturulabilir;

SELECT BÖLÜM_NO,COUNT(ADI) AS SAYI,


SUM(ÜCRET) AS TOPLAM,
AVG(ÜCRET) AS ORTALAMA
FROM PERSONEL
GROUP BY BÖLÜM_NO;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

69
2.6.1 GROUP BY Kullanırken Dikkat Edilecek Noktalar

SELECT deyimi içinde grup fonksiyonları, sütun isimleri ile birlikte kullanılabilirler.
Ancak grup fonksiyonları; GROUP BY sözcüğü olmadan aşağıda gösterildiği biçimde,
sütun isimleri ve grup fonksiyonu ile birlikte kullanılamaz. Örneğin;

SELECT BÖLÜM_NO, COUNT(*)


FROM PERSONEL;

biçiminde bir tanım yapılamaz. Böyle bir amaca ancak aşağıda gösterildiği biçimde
varılabilir;

SELECT BÖLÜM_NO, COUNT(*)


FROM PERSONEL
GROUP BY BÖLÜM_NO;

Bu son sorgu; her bir bölüm numarasını ve bu bölümlerdeki personel sayısını


vermektedir.

GROUP BY ile birlikte sütunların takma isimleri kullanılamaz.

GROUP BY ie tanımlanan grupların, burada belirtilen sütunlara göre artan sırada


olduğu varsayılır. Sırayı test yönde değiştirmek söz konusu ise ORDER BY kullanılır.
GROUP BY içinde belirtilen sütun isimleri, grup fonksiyonu içinde yer almak zorunda
değildir. Örneğin, her bölümün numarası ve ortalama ücretlerini birlikte elde etmek
için SELECT deyimi şu şekilde oluşturulabilir;

SELECT BÖLÜM_NO, AVG(ÜCRET)


FROM PERSONEL
GROUP BY BÖLÜM_NO;
GROUP BY içinde belirtilen sütun isimleri , SELECT listesinde yer almak zorunda

70
değildir. Örneğin; bölüm numarasına göre oluşturulan grupta, yani her bölümün ücret
ortalamalarının görüntülenmesi için şöyle bir tanım yapılabilir;

SELECT AVG(ÜCRET)
FROM PERSONEL
GROUP BY BÖLÜM_NO;

2.6.2 Birden Fazla Sütuna Göre Gruplama


GROUP BY ile bir sütuna göre gruplama yapılabildiği gibi, birden fazla sütun için de
gruplama yapılabilir.

Örnek

Her bölümü ve bölüm içindeki görevlere göre personeli gruplayarak bu bazda ücret
toplamları elde etmek amacıyla SELECT deyimi şu şekilde düzenlenebilir;

SELECT BÖLÜM_NO,GÖREVİ, SUM (ÜCRET) AS TOPLAM_ÜCRET


FROM PERSONEL
GROUP BY BÖLÜM_NO,GÖREVİ;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

71
2.6.3 Grup Koşullarının Kullanımı
Grup işlemleri yerine getirilirken, doğal olarak grup bazında bazı sınırlamalar söz konusu
olabilir. Örneğin, bölüm bazında yapılan bir işlemin, bölüm ücret ortalamasının 2000'den
büyük ise gerçekleştirilmesi istenebilir. Bunun için aşağıda gösterildiği biçimde bir tanım
yapılabilir;

SELECT BÖLÜM_NO, AVG(ÜCRET)


FROM PERSONEL
WHERE AVG(ÜCRET)>2000
GROUP BY BÖLÜM_NO;

Ancak bu deyim istenildiği biçimde çalışmayacak ve bir hatalı durumla karşılaşılacaktır


çünkü, grup koşulları WHERE içinde tanımlanamaz. Onun yerine HAVING sözcüğü
kullanılır. Bu sözcük SELECT deyimi içinde şu şekilde tanımlanır;

Örnek 1

PERSONEL tablosunu göz önüne alalım. Ortalama ücreti 3500'den daha fazla olan
bölümlerin bölüm numarası ve o bölümdeki en yüksek ücret miktarı görüntülenecektir.
Amacımıza uygun SELECT deyimi şu şekilde olabilir;

SELECT BÖLÜM_NO, MAX(ÜCRET) AS EN_ÇOK


FROM PERSONEL
GROUP BY BÖLÜM_NO
HAVING AVG(ÜCRET)>3500;

72
Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

Örnek 2

PAZARLAMA bölümü dışında çalışan personeli görevlerine göre gruplandırılarak ücretleri


toplanacak ve toplam ücreti 5000 den fazla olanlar seçilecektir. Sonuçlar en düşük ücret
toplamından büyüğe doğru sıralı olacaktır. Amacımıza uygun SELECT deyimi şu şekilde
düzenlenebilir;

SELECT GÖREVİ, SUM(ÜCRET) AS TOPLAM


FROM PERSONEL
WHERE GÖREVİ <>'PAZARLAMACI'
GROUP BY GÖREVİ
HAVING SUM(ÜCRET)>5000
ORDER BY SUM(ÜCRET);

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

73
74
75
76
77
78
79
ÇOKLU TABLOLAR VE KARMAŞIK SORGULAR

Bu bölümde;

• Çoklu Tabloların Kullanımı


• Tabloların Birleştirilmesi
• Kartezyen Çarpım
• Birleştirme Türleri
• Küme İşleçlerini Kullanarak Birleştirme
• Alt Sorgu Kavramı
• Çoklu Satır Alt Sorgusu
• Çok Sütunlu Alt Sorgular
• FROM Sözcüğü İçinde Alt Sorgu Tanımlama

anlatılmaktadır.

Bölüm Hedefi
Bu bölümde aşağıda sıralanan konular ele alınarak
incelenecektir:

• Sorgularda birden fazla tablo kullanımı


• Tabloların birleştirilmesi
• Birleştirme türleri
• "Eşiti olan birleştirme" nedir ?
• Eşiti olmayan birleştirme
• Dış birleştirme
• Kendine birleştirme
• Küme operatörleriyle birleştirme
• Alt sorgular nasıl oluşturulur ?
• Çoklu satır alt sorguları

• FROM sözcüğü içinde alt sorgu tanımlama

3.1 Çoklu Tabloların Kullanımı


Bazı uygulamalarda veri birden fazla tablo üzerinde yer alabilir. Bu tablo verileri
birleştirilerek sonuçlar elde edilir. Bu bölümde PERSONEL ve BÖLÜM tablolarını bu
amaçla kullanacağız.

• PERSONEL_NO sütunu PERSONEL tablosu üzerindedir.


• BÖLÜM_NO sütunu hem PERSONEL hem de BÖLÜM tablosu üzerinde vardır.
• KONUM sütunu BÖLÜM tablosundadır.

80
Bu iki tablo arasında ortak olan BÖLÜM_NO sütunları aracılığıyla bir ilişki kurulur ve her
iki tablo verilerinden oluşan bir sonuç elde edilir.

! "Birleştir" düğmesine tıklayınız.

3.2 Tabloların Birleştirilmesi


Birden fazla tablonun ele alınarak, birleştirilmesi ve tek bir sonucun üretilmesi söz konusu
olabilir. Bu işleme "birleştirme" (join) denir. Birleştirme işlemi, tabloların aynı değerler
içeren sütunları kullanılmak suretiyle yapılır. Birleştirme işlemi şu şekilde tanımlanır;

81
Tanımdan görüldüğü gibi, iki tabloyu birleştirmek için bir birleştirme koşulunun
düzenlenmesi gerekiyor. Bu koşul, her iki tablonun hangi sütunları kullanılarak
birleştirileceğini belirler. Sütun isimlerinin ön tarafına, tablo isimlerinin yazılması yararlı
olacaktır. Özellikle her iki tablodaki sütun isimleri aynı ise, söz konusu sütunların hangi
tablodan geldiğini belirtmek mümkün olamayacak ve bu durumda SELECT deyimi
çalışmayacaktır.

Sadece iki tablo değil n sayıda tablo da birleştirilebilir. Ancak bu durumda en az (n-1)
birleştirme koşulu tanımlanmalıdır. Yani, dört adet tabloyu birleştirmekiçin en az üç
birleştirme koşulu olmalıdır. Bu koşul, birleştirilmiş birincil anahtara sahip tablolar için
geçerli olmayacaktır.

3.3 Kartezyen Çarpım


İki tablo arasında birleştirme koşulu tanımlanmamış ise, sonuç olarak bir kartezyen
çarpım elde edilir. Bunun dışında, birleştirme koşulu geçersiz ise ve birinci tablodaki tüm
satırlar ikinci tablodaki tüm satırlarla birleştirilemiyorsa, yine kartezyen çarpımdan söz
edilir.

Örnek

PERSONEL ve BÖLÜM tablolarını göz önüne alalım. Bu iki tabloyu aşağıda görüldüğü
biçimde birleştirmek istiyoruz.

SELECT PERSONEL_NO, ADI,BÖLÜM_ADI


FROM PERSONEL, BÖLÜM

Bu sorgu çalıştırıldığında, PERSONEL ve BÖLÜM tabloları birleştirilerek bir sonuç elde


edilir. Ancak, herhangi bir birleştirme koşulu tanımlanmadığı için, her iki tablodaki
satırların sayısının birbirleriyle çarpımı kadar satırdan oluşan bir sonuç elde edilir.
Örneğin; PERSONEL tablosunda 20, BÖLÜM tablosunda ise 5 satır varsa, bu şekildeki
bir sorgu sonucunda 20x5=100 satordan oluşan bir sonuç bulunur.

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

82
3.4 Birleştirme Türleri
Tabloları farklı şekillerde birleştirme olanağı bulunmaktadır. Solda, tabloları birleştirme
türleri verilmiştir. Bu birleştirme türlerinin herbirini ayrıntılı biçimde ele alarak
inceleyeceğiz.

! Birleştirme türlerini tekrar görmek için 'TEKRAR' düğmesine tıklayınız.

3.4.1 Eşiti Olan Birleştirme

83
Bu tür birleştirmelere "basit birleştirme", "eşiti olan birleştirme" ya da "iç birleştirme"
isimleri verilmektedir. Bu birleştirme aşağıda belirtildiği biçimde gerçekleştirilir;

Bir personelin çalıştığı bölümün adını elde etmek için; PERSONEL tablosu, BÖLÜM
tablosunun BÖLÜM_NO isimli sütununun içeriği ile karşılaştırılır. Yani her iki tablo
arasındaki BÖLÜM_NO sütununun içerdiği değerlerin eşit olması durumunda birleştirme
gerçekleştirilmiş olur.

3.4.1.1 Eşiti Olan Birleştirme İle Kayıtların Seçilmesi


Eşiti olan birleştirmelere örnek olarak aşağıdaki sorguyu düzenliyoruz;

Bu deyim şu şekilde yorumlanacaktır;

PERSONEL tablosundan alınan sütunlar PERSONEL ön ekiyle


tanımlanmıştır. Örneğin, PERSONEL.PERSONEL_NO gibi. Bu
durumda PERSONEL tablosundan, PERSONEL_NO,
PERSONEL_ADI,BÖLÜM_NO; BÖLÜM tablosundan ise, BÖLÜM_NO
ve KONUM isimli sütunlarının alınacağı anlaşılmaktadır.

FROM sözcüğü ardından yazılan tablo isimleri, bu birleşme


işlemine tabi tutulacak tabloları belirlemektedir.

WHERE deyimi içinde tanımlanan koşul, PERSONEL tablosunun


BÖLÜM_NO sütunu içeriği ile BÖLÜM tablosunun BÖLÜM_NO
sütunu içeriğinin karşılaştırılmasına neden olacaktır. Bu koşul
gerçekleştiği takdirde, SELECT listesinde belirlenen sütunlar
görüntülenecektir.

84
3.4.1.2 Sütun İsimlerindeki Belirsizlik

Birleştirme işleminde, SELECT listesindeki her bir sütunun, ilgili tablo ile gösterilebildiğini
gördük. Bu, her iki tablodaki alan isimlerinin aynı olması durumunda sorun yaratacaktır.
Örneğin; PERSONEL.BÖLÜM_NO ve BÖLÜM.BÖLÜM_NO yerine sadece BÖLÜM_NO
yazılsaydı, SQL bunu yorumlayamayacaktı çünkü, bu sütunun hangi tablodan alınacağı
belirtilmemiştir. Bu durumda SELECT deyimi hata mesajı verecektir.

Sadece bir tabloda yer alan sütun isimlerinin, yukarıda belirtildiği gibi, tablo isimleri ile
birlikte belirtilmesi zorunluluğu yoktur.

3.4.1.3 Tablolar için Takma İsimlerin Kullanımı


Birleştirme işlemlerinde, birden fazla tablo kullanıldığı için, sütun isimleri ilgili tablo
isimleriyle birlikte kullanılıyordu. Özellikle uzun tablo isimlerinde bu tür sorguları ifade
etmek zorluklar yaratabilir. Gerçek tablo isimleri yerine daha kısa tablo isimleri vermek
mümkündür.

Bu tür bir tanıma FROM sözcüğü içinde yer verilir. Tablonun gerçek isminin hemen
ardından bir boşluk bırakılarak takma isim tanımlanır. SELECT deyiminin herhangi bir
yerinde, gerçek tablo ismi yerine bu takma isim kullanılabilir.

Örnek

Aşağıdaki SELECT deyimini göz önüne alalım;

SELECT PERSONEL.PERSONEL_NO,PERSONEL.ADI,
PERSONEL.BÖLÜM_NO,BÖLÜM.BÖLÜM_ADI,BÖLÜM.KONUM
FROM PERSONEL,BÖLÜM
WHERE PERSONEL.BÖLÜM_NO=BÖLÜM.BÖLÜM_NO;

Sorgu içinde PERSONEL tablosuna P; BÖLÜM tablosuna ise, B takma ismini vererek aynı
sorguyu aşağıda gösterildiği biçimde düzenleyebiliriz;

SELECT P.PERSONEL_NO,P.ADI,
P.BÖLÜM_NO,B.BÖLÜM_ADI,B.KONUM
FROM PERSONEL P,BÖLÜM B
WHERE P.BÖLÜM_NO=B.BÖLÜM_NO;

3.4.1.4 AND İşlecinin Kullanımı


Birleştirme koşuluna ek olarak, WHERE sözcüğü içinde başka koşullara da yer verilebilir.
Örneğin, BEGÜM isimli personelin; personel numarası, adı, bölüm numarası ve
bölümünün konumunu listelemek için şöyle bir sorgu tanımlanabilir:

85
SELECT P.PERSONEL_NO,P.ADI,B.BÖLÜM_ADI,B.KONUM
FROM PERSONEL P, BÖLÜM B
WHERE P.BÖLÜM_NO=B.BÖLÜM_NO
AND P.ADI='BEGÜM';

3.4.2 Eşiti Olmayan Birleştirme


Eşiti olan birleştirmelerde, iki tablonun belirlenen iki sütununun içeriği karşılaştırılıyor ve
her iki sütunda aynı değerle karşılaşınca ilgili bilgiler listeleniyordu. Eğer, birinci tablonun
bir sütununa ikinci tabloda doğrudan uyan bir sütun yoksa, eşiti olmayan
birleştirmelerden söz edilir.

3.4.3 Dış Birleştirme


Eşiti olan birleştirmelerde; bir tablonun bir sütununun içerdiği değerler, diğer tablonun
ilgili sütununda eşleştiriliyor ve ancak eşleşebilen değerler birleştiriliyordu. Doğal olarak,
eşleşemeyen satırlar birleştirilemeyecek ve sonuca dahil edilemeyecektir.

Eğer bu şekilde eşleşemeyen kayıtların da sonuca dahil edilmesi isteniliyorsa; dış


birleştirme yönteminin uygulanması gerekecektir. Örneğin, PERSONEL ve BÖLÜM
tablolarının aşağıda gösterildiği biçimde olduğunu varsayalım.

86
Bu iki tablo incelendiğinde, BÖLÜM tablosunda yer alan REKLAM bölümünde herhangi
bir personelin çalışmadığı görülecektir. İki tablo; eşiti olan birleştirme yöntemine göre
birleştirilirse, sonuç içinde bu bölüm adı görüntülenmeyecektir. Böyle durumlarda
eşleşmeyen kayıtları da birleştirme işlemine katmak için; dış birleştirme yöntemi
uygulanır.

3.4.3.1 Dış Birleştirme Nasıl Tanımlanır ?


Dış birleştirmeler, eşleşmeyen kayıtlar hangi tabloda yer alıyorsa ona bağlı olarak iki
farklı biçimde düzenlenebilir:

SELECT tablo1.sütun1,
tablo2.sütun2
FROM tablo1, tablo2
WHERE
tablo1.sütun1(+)=tablo2.sütun2

veya

SELECT tablo1.sütun1,
tablo2.sütun2
FROM tablo1, tablo2
WHERE
tablo1.sütun1=tablo2.sütun2(+)

Tanımda (+) işaretlerinin yer alması, dış birleşme olayının olduğunu göstermektedir. Bu
işaret eksik bilginin olduğu tarafa yerleştirilir.

Örnek

87
PERSONEL ve BÖLÜM tablolarını göz önüne alalım. BÖLÜM tablosunda yer alan, ancak
PERSONEL tablosunda yer almayan ve REKLAM bilgisini içeren bir satır bulunmaktadır.
Bu iki tabloyu, karşılaşmayan kayıtları da görüntüleyecek biçimde birleştirmek ve sonucu
listelemek istiyoruz. Bunun için aşağıdaki yol izlenir:

SELECT P.ADI,P.BÖLÜM_NO,B.BÖLÜM_ADI
FROM PERSONEL P,BÖLÜM B
WHERE P.BÖLÜM_NO(+)=B.BÖLÜM_NO;

Bilgi eksikliği PERSONEL tablosundadır çünkü, BÖLÜM tablosunda yer alan REKLAM
satırı, PERSONEL tablosunda yoktur. O halde (+) işareti, PERSONEL tablosunun ilgili
sütunu yanında tanımlanmıştır. Bu işlemin aynısını MS Jet SQL'de gerçekleştirmek için
biraz daha farklı tanım yapmak gerekiyor. Bu tür bir dış birleşme için LEFT JOIN…ON
sözcükleri kullanılır.

SELECT P.ADI, B.BÖLÜM_ADI


FROM BÖLÜM B LEFT JOIN PERSONEL P
ON B.BÖLÜM_NO = P.BÖLÜM_NO;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

88
3.4.4 Kendine Birleştirme
Bazı uygulamalarda birleştirme işlemi, iki ayrı tablo yerine tek bir tablodaki veriler
kullanılarak yapılır. Örneğin, PERSONEL tablosunu aşağıda görüldüğü gibi, iki farklı tablo
biçiminde düşünebiliriz. Böylece bu iki tabloyu birleştirerek çeşitli sonuçlar elde etmek
imkânımız vardır.

Örnek

PERSONEL tablosunun YÖNETİCİSİ başlıklı sütunu; her bir personelin yöneticisinin,


personel numarasını içermektedir. Hangi yöneticilerin hangi personel ile çalıştığını
belirlemek istiyoruz. Bu amaçla SELECT deyimi şu şekilde düzenlenebilir:

SELECT P.PERSONEL_NO AS NO, P.ADI AS PERSONEL, Y.ADI AS YÖNETİCİSİ


FROM PERSONEL P, PERSONEL Y
WHERE Y.PERSONEL_NO=P.YÖNETİCİSİ;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

89
3.5 Küme İşleçlerini Kullanarak Birleştirme
SQL deyimleri içinde küme işlemlerini temel alarak, çeşitli sorgulamalar yapılabilir. Bu tür
sorgularda küme işleçlerinden yararlanılır. Küme işleçleri sayesinde birden fazla tablo
birleştirilerek sonuçlar alınabilir.

! SQL'de kullanılan küme işleçlerini tekrar görmek için 'TEKRAR' düğmesine tıklayınız.

90
3.5.1 UNION ve UNION ALL İşleçleri
UNION işleci; verilen koşul ifadesine uygun olarak çift kayıtları göz ardı eder ve her iki
kümedeki tüm kayıtları seçer. Buna karşılık, verilen koşul ifadesine uygun olarak çift
kayıtlar da dahil olmak üzere, tüm kayıtların seçilmesi söz konusu ise; UNION ALL işleci
kullanılır.

Union İşlecinin Etkisi

Örnek

PERSONEL tablosunda, adı "A" ile başlayanları veya görevi "M" ile başlayanları topluca
listelemek istiyoruz.

Burada iki ayrı koşuldan söz edilebilir. Bunlardan birincisi, adının ilk harfi "A" ile başlayan
personelin oluşturduğu kümedir. İkincisi ise; görevi "M" harfi ile başlayanların
oluşturduğu kümedir.

A={Adı "A" harfi ile başlayan personel}


B={Görevi "M" harfi ile başlayan personel}

Bu durumda sorgu içinde; UNION işlecinin kullanılması gerektiği anlaşılmaktadır.


SELECT deyimi şu şekilde düzenlenir:

SELECT ADI, GÖREVİ


FROM PERSONEL
WHERE ADI LIKE 'A%'
UNION
SELECT ADI, GÖREVİ
FROM PERSONEL
WHERE GÖREVİ LIKE 'M%';

Bu deyim çalıştırıldığında, birbirinin aynı olan yani, çift kayıtlar görüntülenmez. Eğer çift
kayıtların da görüntülenmesi isteniliyorsa; UNION ALL işleci kullanılır.

91
3.5.2 INTERSECT İşleci
Her iki koşula da uygun kayıtları elde etmek için; INTERSECT işleci kullanılır. Bu işleç, iki
kümenin ara kesiti olarak düşünülür ve iki bölgedeki kayıtların seçilmesini sağlar.

INTERSECT İşlecinin Etkisi

Örnek

PERSONEL tablosunda, adı "A" ile başlayanları ve görevi "M" ile başlayan kayıtları
bulacağız. Amacımıza uygun SELECT deyimi şu şekilde olabilir:

SELECT ADI, GÖREVİ


FROM PERSONEL
WHERE ADI LIKE 'A%'
INTERSECT
SELECT ADI, GÖREVİ
FROM PERSONEL
WHERE GÖREVİ LIKE 'M%';

3.5.3 MINUS İşleci


Birinci kümede olan, ikinci kümede olmayan kayıtları seçmek amacıyla; MINUS
işlecinden yararlanılabilir.

92
MINUS İşlecinin Etkisi

Örnek

Adı "A" ile başlayan ancak işi, "M" ile başlamayan kayıtları listelemek gerektiğinde;
MINUS işlecine başvurulur. Bunun anlamı, birinci sorguda ismi "A" ile başlayanlar; ikinci
sorguda da işi, "M" ile başlayanlar aranılacaktır. MINUS işleci, bu iki küme arasındaki
farkı ortaya çıkaracaktır.

A={Adı "A" harfi ile başlayanlar}


B={Görev adı "M" harfi ile başlayanlar}

Amacımıza uygun SELECT deyimi şu şekilde düzenlenebilir:

SELECT ADI, GÖREVİ


FROM PERSONEL
WHERE ADI LIKE 'A%'
MINUS
SELECT ADI, GÖREVİ
FROM PERSONEL
WHERE GÖREVİ LIKE 'M%';

3.6 Alt Sorgu Kavramı


Şu ana kadar ele alarak incelediğimiz tüm sorgular; önceki bölümde öğrendiğimiz işleçler
yardımıyla yapılan birleştirmeler dışında, tek bir ana sorgudan oluşuyordu. Dolayısıyla,
sorgu içinde sadece bir SELECT deyimine yer veriliyordu.

Uygulamada, bir sorgudan elde edilen sonuç, bir diğer sorguyu ilgilendirebilir. Bu gibi
durumlarda alt sorgular ya da bir başka deyişle iç sorgular kullanılır.

Şu soruyu göz önüne alalım: "Hangi personelin ücreti, "HALİT" isimli personelin
ücretinden daha fazladır?" Bu problemi iki farklı sorguya ayırmak mümkündür:

Sorgu 1: "HALİT" isimli personelin aylık ücreti nedir?


Sorgu2: Hangi personelin ücreti, "HALİT" isimli personelin ücretinden daha fazladır?

93
Yukarıdaki iki sorguyu aşağıdaki şekilde analiz ederek bir sorgu biçimine döndürebiliriz.
Alt sorgular bu amaçla tanımlanır.

3.6.1 Alt Sorgunun Tanımlanması


Bir alt sorgu aşağıda gösterildiği biçimde tanımlanır:

SELECT liste
FROM tablo
WHERE ifade
işleç
(SELECT liste
FROM tablo);

Tanımda görüldüğü gibi, iki SELECT deyimi ile bir farklı sorgu tanımlanmıştır. Bu iki
sorgu birbirine WHERE koşul sözcüğü içinde bağlanmıştır. Bir alt sorgu, aşağıdaki
sözcükler içinde kullanılabilir:

• WHERE
• HAVING
• FROM

Örnek

Personel numarası "110" olan personelin ücretinden daha fazla ücret alan personel
isimlerini listelemek istiyoruz. Amacımıza uygun SELECT deyimi şu şekilde olabilir:

SELECT ADI,ÜCRET
FROM PERSONEL
WHERE ÜCRET >
( SELECT ÜCRET
FROM PERSONEL
WHERE PERSONEL_NO=110 );

94
Bu sorgu çalıştırıldığında, şöyle bir yol izlenecektir:

a. Alt sorgu Personel numarası "110" olan personelin ücretini bulacaktır. Bu ücret;
"5000" dir.
b. Elde edilen ücret bilgisi ana sorgudaki WHERE sözcüğü içinde yerine konulacaktır.
Yani ana sorgunun WHERE koşulu şu şekli almış olacaktır:
WHERE ÜCRET > 5000
c. Ana sorgu bu şekilde çalışır. Yani ücreti "5000" den fazla olan personelin listesi
görüntülenir.

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

3.6.2 Alt Sorgu Düzenleme Kuralları


Alt sorgular düzenlenirken aşağıdaki kurallara uymak gerekmektedir:

95
3.6.3 Tek Satır Alt Sorguları
Sadece bir değer döndüren alt sorgulardır. İç taraftaki SELECT deyiminden sadece tek bir
değer elde edilir. Bu sorgularda soldaki animasyonda yer alan işleçler kullanılır.

! Karşılaştırma İşleçleri ve anlamlarını tekrar görmek için TEKRAR düğmesine tıklayınız.

96
Örnek 1

Personel numarası "140" olan personelle aynı göreve sahip olan personelin isimlerini
listelemek istiyoruz. Amacımıza aşağıdaki sorgu yardımıyla ulaşabiliriz:

SELECT ADI,GÖREVİ
FROM PERSONEL
WHERE GÖREVİ =
(SELECT GÖREVİ
FROM PERSONEL
WHERE PERSONEL_NO=140);

Bu sorgu çalıştırıldığında, alt sorgu sonucunda "140" numaralı personelin görevi, yani
"ŞEF" değeri elde edilir. Ana sorgu ise görevi "ŞEF" olanları sorgular.

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

Örnek 2

Personel numarası "155" olan personelle aynı göreve sahip olan ve "350" numaralı
personelin ücretinden daha fazla ücret alan personeli listelemek istiyoruz.

SELECT ADI,GÖREVİ,ÜCRET
FROM PERSONEL
WHERE GÖREVİ =
(SELECT GÖREVİ
FROM PERSONEL
WHERE PERSONEL_NO=155)

97
AND ÜCRET>
(SELECT ÜCRET
FROM PERSONEL
WHERE PERSONEL_NO=350);

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

3.6.4 Grup Fonksiyonlarının Kullanımı


Grup fonksiyonları sadece bir değer döndürdüğü için, bu tür fonksiyonlar tek satır alt
sorgularında kullanılabilir.

98
Örnek

Personel arasında en az ücret alanları listelemek istiyoruz. Bu sorgu doğal olarak alt
sorgularla yapılabilir. Önce alt sorgu içinde en az ücret alan personel belirlenecek,
bulunan değer ana sorgu içinde bu ücrete göre seçilecektir. Amacımıza uygun SELECT
deyimi şu şekilde olabilir:

SELECT ADI,ÜCRET
FROM PERSONEL
WHERE ÜCRET =
(SELECT MIN(ÜCRET)
FROM PERSONEL);

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

99
3.6.5 HAVING ile Grup Koşullarının Tanımlanması
Ana sorgu grup fonksiyonu içeriyorsa, doğal olarak grup koşullarının tanımlanması
gerekebilecektir. Yani HAVING sözcüğü de kullanılacaktır. Bu durumda SELECT deyimi şu
şekli alacaktır:

SELECT liste
FROM tablo
GROUP BY sütun
HAVING fonksiyon işleç
(SELECT fonksiyon
FROM tablo);

100
Örnek

En düşük ücreti "20" numaralı bölümün en düşük ücretinden daha büyük olan bölümleri
listelemek istiyoruz. Amacımıza ulaşmak için şu şekilde bir akıl yürüteceğiz: :

a) "20" numaralı bölümün en az ücret alan personeli belirlenecektir.


b) Bulunan bu değer, diğer tüm bölümlerin en düşük ücretleriyle karşılaştırılacak
c) Eğer bu değer bölümlerin en düşük ücretlerinden daha küçük ise ilgili bölüm
listelenecektir.

Belirtilen bu adımlara uygun SELECT deyimi şu şekilde olabilir:

SELECT BÖLÜM_NO,MIN(ÜCRET) AS ENAZ_ÜCRET


FROM PERSONEL
GROUP BY BÖLÜM_NO
HAVING MIN(ÜCRET) >
(SELECT MIN(ÜCRET)
FROM PERSONEL
WHERE BÖLÜM_NO=20);

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

101
3.6.5 Alt Sorgularda Hatalı Çalışma Durumu
Tek satır alt sorgularının yapısını ve özelliklerini biliyoruz. Bu tür alt fonksiyonlar, sadece
bir değer üreterek, onu ana sorguya aktarır. Eğer alt sorgu tek satırlı alt sorgu olarak
düşünülüyorsa, bunu bozabilecek tanımlardan kaçınmak gerekiyor. Aksi takdirde söz
konusu sorgu çalışmaz. Eğer alt sorgunun birden fazla değer üretmesi söz konusu ise,
çoklu satır alt sorgularını tanımlamak gerekiyor.

102
Örnek

Aşağıdaki alt sorguyu göz önüne alalım.

SELECT PERSONEL_NO,ADI
FROM PERSONEL
WHERE ÜCRET >
(SELECT MIN(ÜCRET)
FROM PERSONEL
GROUP BY BÖLÜM_NO);

Bu sorgu çalıştırıldığında, amaca ulaşılamayacaktır. Çünkü alt sorgu gruplandırılmıştır ve


doğal olarak grup fonksiyonu herbir grup için bir değer üretir. Yani birden fazla satır
listelenecektir. Ancak ana sorgunun WHERE sözcüğü içinde kullanılan (=) işleci bir tek
satır işlecidir. Alt sorgudan sadece bir değer beklemektedir. Bu durum gerçekleşmediği
için SELECT deyimi bir hata mesajı görüntüleyerek işlemi sonlandırır. Aynı sorgu şu
şekilde düzenlenseydi hata durumu ortaya çıkmayacaktı:

SELECT PERSONEL_NO,ADI
FROM PERSONEL
WHERE ÜCRET >
(SELECT MIN(ÜCRET)
FROM PERSONEL);

3.7 Çoklu Satır Alt Sorgusu


Alt sorgudan bir satır yerine, daha fazla sayıda satır elde ediliyorsa, bu kez sorgu bir
çoklu satır alt sorguları olarak değerlendirilir. Ancak bu tür sorgular farklı işleçler
yardımıyla gerçekleştirilir. Aşağıdaki animasyonda çoklu satır işleçlerine yer veriyoruz.

103
Yukarıda sayılan işleçlerden hiçbiri NOT işleci ile birlikte kullanılamaz!

3.7.1 IN İşleci
Bir liste içindeki değerlerden birini seçmek için IN işlecini kullanıyorduk. Örneğin,

SELECT ADI, ÜCRET,GÖREVİ


FROM PERSONEL
WHERE ÜCRET IN(2000,2500,3000);

biçimindeki bir sorgu, ÜCRET sütunu içeriğinin, IN işleci ile belirlenen listedeki değerlerle
karşılaştırılmalarını sağlıyordu. Bu tür bir işlem, alt sorgularda da gerçekleştirilebilir.

Örnek

Bir liste içindeki değerlerden birini seçmek için IN işlecini kullanıyorduk. Örneğin,

104
SELECT ADI,ÜCRET,GÖREVİ
FROM PERSONEL
WHERE ÜCRET IN(
SELECT MIN(ÜCRET)
FROM PERSONEL
GROUP BY BÖLÜM_NO);

biçimindeki bir sorgu, ÜCRET sütunu içeriğinin, IN işleci ile belirlenen listedeki değerlerle
karşılaştırılmalarını sağlıyordu. Bu tür bir işlem, alt sorgularda da gerçekleştirilebilir.

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

3.7.2 ANY İşleci


Alt sorgu tarafından üretilen herbir değeri ana sorgu içinde belirlenen bir değerle
karşılaştırmak söz konusu ise ANY işleci kullanılır. Bu işleç "=,<,>" işleçlerinden biri ile
birlikte kullanılır. "=ANY" biçimindeki bir tanım IN tanımı ile eşdeğerdir. "<ANY" ifadesi
"en çoktan daha az"; ">ANY" ise "en azdan daha büyük" anlamında değerlendirilir.

105
Örnek 1

En fazla kazanan MEMUR dan daha az maaşı olan personeli listelemek istiyoruz.
Amacımıza uygun sorgu şu şekilde olabilir.

SELECT ADI,ÜCRET,GÖREVİ
FROM PERSONEL
WHERE ÜCRET <ANY(
SELECT ÜCRET
FROM PERSONEL
WHERE GÖREVİ='MEMUR');

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

106
Örnek 2

En düşük ücretli MEMUR dan daha fazla maaşı olan personeli listelemek için aşağıda
belirtilen yol izlenebilir:

SELECT ADI,ÜCRET,GÖREVİ
FROM PERSONEL
WHERE ÜCRET >ANY(
SELECT ÜCRET
FROM PERSONEL
WHERE GÖREVİ='MEMUR');

3.7.3 ALL İşleci


Alt sorgu tarafından üretilen tüm değerlerin, ana sorgu için bir girdi olarak kullanılması
söz konusu ise ALL işleci kullanılabilir. ">ALL" ifadesi "en büyükten daha büyük";
"<ALL" ise "en küçükten daha küçük" olanları ifade eder.

107
Örnek

Ücreti tüm bölümlerin ortalama ücretinden daha büyük olan personellerii listelemek
istiyoruz. Amacımıza uygun sorgu şu şekilde olabilir:

SELECT ADI,ÜCRET
FROM PERSONEL
WHERE ÜCRET >ALL(
SELECT AVG(ÜCRET)
FROM PERSONEL
GROUP BY BÖLÜM_NO);

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

108
3.8 Çok Sütunlu Alt Sorgular
Önceki bölümde, alt sorgunun ürettiği bir sütun, ana sorgu için bir girdi olarak
kullanılıyordu. Bazı uygulamalarda alt sorgunun birden fazla sütun üretmesi ve koşul
içinde bu değerlerin kulanılması söz konusu olabilir. Böyle durumlarda aşağıda belirtildiği
biçimde sorgu tanımlanır. Bu tür bir tanım MS Access'de, yani MS Jet SQL'de geçerli
değildir.

SELECT liste
FROM tablo
WHERE sütun1, sütun2,... IN
( SELECT sütun1, sütun2,...
FROM tablo
WHERE koşul );

109
Örnek

"SEZİN" isimli personelin görevi ve ücretiyle aynı olan personeli listelemek istiyoruz.
Sorgu şu şekilde düzenlenebilir:

SELECT BÖLÜM_NO, ADI,ÜCRET


FROM PERSONEL
WHERE (GÖREVİ,ÜCRET) IN
(SELECT GÖREVİ,ÜCRET
FROM PERSONEL
WHERE ADI='SEZİN');

Ancak bu sorguya "SEZİN" in kendi bilgileri de dahil edilmiştir. Dahil edilmesi


istenmiyorsa şu şekilde bir tanım yapılır:

SELECT BÖLÜM_NO, ADI,ÜCRET


FROM PERSONEL
WHERE (GÖREVİ,ÜCRET) IN
(SELECT GÖREVİ,ÜCRET
FROM PERSONEL
WHERE ADI='SEZİN')
AND ADI<>'SEZİN';

3.9 FROM Sözcüğü İçinde Alt Sorgu Tanımlama


Normal olarak bir SELECT deyiminde kullanılabilecek tablolar, yani veri kaynağı FROM
sözcüğü içinde tanımlanır. Ancak gerektiğinde bir alt sorgunun sonuçları da tıpkı bir tablo
gibi değerlendirilerek, FROM içinde bu sorgu yer alabilir.

Örnek

Bir bölümün ortalama ücretinden daha fazla ücret alan tüm personelin ortalama
ücretlerini listelemek istiyoruz. Amacımıza uygun sorgulama şu şekilde olabilir:

SELECT P.BÖLÜM_NO, P.ADI,P.ÜCRET, S.MAAŞ


FROM PERSONEL P,(SELECT BÖLÜM_NO,AVG(ÜCRET) AS MAAŞ

110
FROM PERSONEL
GROUP BY BÖLÜM_NO) S
WHERE P.BÖLÜM_NO=S.BÖLÜM_NO
AND P.ÜCRET>S.MAAŞ;

Burada, PERSONEL tablosu yanısıra bir alt sorgu tanımlanmaktadır. Bu sorgu tıpkı bir
tablo gibi düşünülerek ona S adı verilmiştir. Bu sorgu bölümlerin ücret ortalamalarını
üretmektedir.

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

111
112
113
114
115
116
117
118
119
VERİTABANI TABLOLARININ YARATILMASI

Bu bölümde;

• Tablolar
• DML İşlemleri
• Hareket İşleme

anlatılmaktadır.

Bölüm Hedefi
Bu bölümde aşağıda sıralanan konular ele alınarak
incelenecektir:

• DML
• Tablolara yeni satır ekleme
• Tablodaki verilerin güncelleştirilmesi
• Tablodan satır silme işlemi
• Hareket işleme

• Hareketin başlatılması ve sona erdirilmesi

4.1 Tablolar
Tablolar veri tabanının temel yapılarıdır. Tablo yapılarının en önemli özellikleri şunlardır:

a) Tablolar herhangi bir anda, hatta veri tabanının bir kullanıcı tarafından kullanılması
esnasında bile yaratılabilir.

b) Tablolar için bir boyut belirlemeye gerek yoktur. Ancak yine de tablonun ne kadarlık
bir hacime ulaşabileceğini tahmin etmekte yarar vardır.

120
Veri tabanlarında iki türlü tablo yer almaktadır:

Bu tablolar herhangi bir veri tabanı kullanıcısı tarafından yaratılan


Kullanıcı
tablolardır. Söz konusu tabloların isimleri ve sütunları doğal olarak
tabloları
kullanıcı tarafından belirlenmiştir.

Veri tabanı sunucusu tarafından kullanılan ve bakımı onun


tarafından yapılan tablolardır. Veri tabanının yönetilmesine yönelik
olan bu tablolar ve görünümler (views), veri tabanı sözlüğünü
Veri sözlüğü
(database dictionary) oluştururlar. Bu tablolara sistem yöneticisi
dışında herhangi bir kullanıcının erişmesi ya da müdahale etmesi
mümkün değildir.

4.1.1 Tabloları İsimlendirme


Tablolara doğal olarak bir isim vermek gerekecektir. İsimlendirirken bazı kurallara uymak
gerekmektedir:

121
Tablo isimleri büyük-küçük harf ayrımına karşı duyarlı değildir. Küçük harflerle ya da
büyük harflerle veya karışık yazılması fark etmez. Tablo isimleri verilirken aşağıda
sıralanan hususlara dikkat edilmesi tavsiye edilir:

a) Tablo ya da sütun isimleri ilişkili olduğu konuya uygun biçimde belirlenmelidir.

Aynı sütunlar birden fazla tablo içinde yer alıyorsa, aynı isimleri vermek yararlı
b) olacaktır. Örneğin PERSONEL ve BÖLÜM tablosu içindeki bölüm numarasını içeren
sütunlar BÖLÜM_NO biçiminde belirlenmiştir.

4.1.2 Veri Türleri


Tablolar yaratılırken, her bir sütunun veri türü mutlaka belirlenmelidir Çeşitli amaçlara
uygun veri türleri bulunmaktadır. ORACLE sunucuda geçerli olan bu veri türlerinin temel
olanlarını soldaki; tamamını ise aşağıdaki canlandırmada görebilirsiniz:

122
123
124
125
126
127
4.1.3 Tabloların Yaratılması
Tabloların yaratılabilmesi için CREATE TABLE deyimi kullanılır. Bu deyim şu şekilde
tanımlanır:

CREATE TABLE [şema.] tablo


(sütun veri türü [DEFAULT ifade],…);

şema Tablonun sahibini belirler


tablo Yaratılacak tablonun adı
sütunlar Tablonun herbir sütunu
veri türü Herbir sütunun veri türü
DEFAULT Sütuna veri girişi yapılmadığında, o sütunun
ifade varsayılan değerini belirler

Veri tabanındaki nesneler topluluğuna şema adı verilebilir.

Şema nesneleri, veri tabanı içindeki verilere doğrudan karşılık gelen mantıksal yapılardır.
Şema nesneleri tablolar, görünümler, dizinler ve diğer nesnelerdir. Bir tablo belirli bir
kullanıcıya ait ise, tablo adı kullanıcı adı ile birlikte ifade edilir.

Bir sütunun değeri, daha tablo yaratılırken varsayılan değer (default value) olarak
atanabilir. Burada doğrudan bir değer, bir ifade veya bir fonksiyon belirlenebilir. Ancak
belirtlenen değer, ilgili sütunun veri türüne uygun olmalıdır. Örneğin, PERSONEL
tablosunun GİRİŞ_TAR isimli alanı, personelin işe giriş tarihini içerecektir. Eğer herhangi
bir değer kaydedilmez ise, bu personelin tabloya kaydedildiği günün tarihini işe giriş tarihi
olarak kabul etmek istiyoruz. Bu amaçla DEFAULT sözcüğü,

128
… GİRİŞ_TAR DATE DEFAULT SYSDATE biçiminde kullanılabilir.

Örnek

BÖLÜM tablosunun aşağıdaki sütunlardan oluşması gerektiğini varsayalım:

BÖLÜM_NO Sayısal değerler içerecektir. En fazla 2 karakter


olabilir.

BÖLÜM_ADI Bölüm adını içerecektir. En fazla 15 karakter


olabilir.

KONUM Bölümün yerini belirleyecekitir. En fazla 13


karakter olabilir.

Bu tablo aşağıda belirtildiği biçimde yaratılabilir:

CREATE TABLE BÖLÜM


(BÖLÜM_NO NUMBER(2),
BÖLÜM_ADI VARCHAR2(15),
KONUM VARCHAR2(13));

4.1.4 Bir Alt Sorgu İle Tabloların Yaratılması


Bir tablo yaratıldıktan sonra, INSERT INTO deyimi yardımıyla, bu tabloya bir başka
tablodan sorgulama işlemi yapılarak bilgi giriş yapılabilir. Ancak, bilgi giriş işlemi daha
tablo yaratılırken de yapılabilir. Bunun için, CREATE TABLE deyimi bir alt sorgu ile
birlikte kullanılabilir.

CREATE TABLE tablo

[(sütunlar)]
AS
altsorgu ;

CREATE TABLE deyiminde sütun tanımları yapılmamış ise, alt sorgudan elde edilen
sütunlar yeni yaratılacak olan tablonun sütunlarını oluşturacaktır. Eğer CREATE TABLE
deyimi içinde sütun tanımları verilmiş ise, bunların sayısı alt sorgudan elde edilen sütun
sayısı ile aynı olmalıdır. Bu durumda yeni tablo sütunları ile alt sorgu sütunları sıraya göre
eşleşir.

129
Örnek

PER20 isimli bir tablo yaratacağız. Bu tablo PERSONEL tablosunda yer alan ve "20"
numaralı bölüme ilişkin personel kayıtlarını içerecektir. PERSONEL tablosundaki aylık
ücret bilgileri yıllığa çevrilerek PER20 tablosuna yazdırılacaktır.

CREATE TABLE PER20


AS
SELECT PERSONEL_NO, ADI, ÜCRET*12 AS YILLIK
FROM PERSONEL
WHERE BÖLÜM_NO=20;

4.1.5 Tabloya Yeni Bir Sütun Ekleme


Bir tablo yaratıldıktan sonra, gerektiğinde yeni sütunlar eklenebilir. Bu amaçla ALTER
deyimi kullanılır. ALTER deyimi şu şekilde tanımlanıyor:

130
ALTER TABLE tablo
ADD ((sütun1 veri türü
[DEFAULT ifade]
[,sütun2 veri türü]…);

! "Alter Table" okuna tıklayınız.

Örnek

Daha önce yaratılan PER20 isimli tabloya GÖREVİ isimli yeni bir sütun eklemek
istiyoruz. Bu sütun VARCHAR2 veri türüne sahip olacak ve en fazla 9 karakter
içerebilecektir. Bunun için şöyle bir yol izlenir:

ALTER TABLE PER20


ADD (GÖREVİ VARCHAR2(9));

4.1.6 Bir Sütun Tanımını Değiştirmek


Tablo yaratıldıktan sonra, gerektiğinde bir sütun ile ilgili tanımlarda bazı değişiklikler
yapılabilir. Bunun için ALTER deyimi MODIFY sözcüğü ile birlikte şu şekilde kullanılır:

131
ALTER TABLE tablo
MODIFY (sütun1 veri türü
[DEFAULT ifade] [,sütun2
veri türü]…);

! "Alter Table" okuna tıklayınız.

Sütun tanımları istenildiği biçimde değiştirilemez. Bu işlemi yerine getirirken bazı


noktalara dikkat etmek gerekiyor:

132
Örnek

PER20 isimli tablonun ADI isimli sütunun genişliğini 15 karakter olarak değiştirmek
istiyoruz. Bunun için aşağıda belirtilen yol izlenir:

ALTER TABLE PER20


MODIFY (ADI VARCHAR2(15));

4.1.7 Tablo Adının Değiştirilmesi


Bir tablo veya diğer veri tabanı nesnelerinin adını değiştirmek gerekebilir. Bu amaçla
RENAME deyimi kullanılır. Bu deyim şu şekilde tanımlanıyor:

RENAME eski adı TO yeni adı;

Nesnenin adını değiştirirken, isimlendirme ile ilgili kurallara uymak gerekmektedir.

133
Örnek

Veri tabanındaki BÖLÜM isimli tablounun adını YENİ_BÖLÜM olarak değiştirmek için
şöyle bir yol izlenebilir:

RENAME BÖLÜM TO YENİ_BÖLÜM;

4.1.8 Tablonun Yok Edilmesi


Gerektiğinde bir tablo veri tabanından silinebilir. Böyle bir amaca ulaşmak için DROP
deyimi kullanılır. Söz konusu deyim şu şekilde tanımlanıyor:

DROP TABLE tablo

! "Drop Table" okuna tıklayınız.

Bu deyim tehlikeli sonuçlara neden olabilecek bir deyimdir. O halde kullanırken bazı
noktalara dikkat etmek gerekiyor:

134
Örnek

PER20 isimli tabloyu yok etmek için aşağıda belirtilen yol izlenir:

DROP TABLE PER20;

4.2 DML Nedir ?


SQL'de SELECT deyimi ile sorgulama işlemleri yapılıyordu. Bunları önceki bölümlerde
ayrıntılı biçimde ele alarak inceledik. Bu tür işlemler, sadece sorgulama yapar. Tablolar
üzerinde herhangi bir değişikliğe yol açmaz.

Eğer bir tabloya yeni kayıt ilave edilmesi, var olan bir satır üzerinde değişiklikler
yapılması veya bir satırın yok edilmesi söz konusu ise, sorgulama deyimleri bir işe
yaramaz. Onun yerine başka yöntemlere başvurmak gerekir.

135
DML-(Data Manipulation Lanquage) adı verilen dil yardımıyla; veri tabanı tabloları
üzerinde kayıt ekleme, veri değiştirme ve kayıt silme gibi işlemler yapılabilir. Bu bölümde
söz konusu dilin temel özelliklerini inceleyeceğiz.

! DML deyiminin görevlerini tekrar görmek için 'TEKRAR' düğmesine


tıklayınız.

4.2.1 Tabloya Satır Ekleme


Bir tabloya yeni bir satır eklemek gerektiğinde INSERT INTO deyimi kullanılır. Bu deyim
aşağıda gösterildiği biçimde tanımlanıyor:

INSERT INTO tablo (sütunlar)


VALUES (değerler);

Kayıt ekleme işleminin yapılacağı tablonun


tablo
adı.
sütunlar Eklenecek satırların sütun isimleri.
değerler Herbir sütuna girilecek yeni değerler.

Bu deyim her çalıştığında tabloya yeni bir satır eklenir. INSERT INTO deyimi içinde sütun
isimlerini belirlemek zorunlu değildir. Ancak, bu durumda sütunların tablo tanımındaki
varsayılan sırası kabul edilir.

136
Örnek

BÖLÜM tablosunun aşağıda görüldüğü biçimde 6 adet kayıta sahip olduğunu varsayalım:

Yukarıda olduğu gibi, herhangi bir tablonun satırlarını nasıl görüntüleyeceğimizi geçen
derslerden biliyoruz. Bu işlem aşağıda belirtildiği biçimde SELECT sorgulama deyimi ile
yapılır:

SELECT *
FROM BÖLÜM;

137
Bu tabloya yeni bir bölüm eklemek istiyoruz. Eklenecek yeni bölüm ile ilgili veriler şu
şekildedir:

Bölümün
: 70
numarası
Bölümün adı : EĞİTİM
Bölümün
: KADIKÖY
konumu

Söz konusu bir kayıtı eklemek için aşağıdaki deyim kullanılır:

INSERT INTO BÖLÜM(BÖLÜM_NO,BÖLÜM_ADI,KONUM)


VALUES(70,'EĞİTİM','KADIKÖY');

Bu şekilde kayıt ekleme işlemi gerçekleştirildikten sonra, BÖLÜM tablosu yeniden


görüntülenirse, tablonun en sonuna söz konusu kayıtın eklendiği görülür.

4.2.2 NULL Değerlerin Tabloya Eklenmesi


Tablonun bir sütununa NULL değerin girilmesi gerekebilir. Bu gibi durumlarda, iki
yöntemden biri kullanılabilir. Birinci yöntemde, INSERT INTO deyimi içinde NULL değeri
girilecek sütun adı belirtilmez. İkinci yöntemde ise, söz konusu sütuna doğrudan NULL
değeri atanır.

Sütun adı belirtilmez.

Sütuna NULL değeri


kaydedilir.

Örnek

BÖLÜM tablosuna yeni bir kayıt ekleyeceğiz. Eklenecek satırda KONUM sütununa NULL
değerini atamak için INSERT INTO deyimi aşağıda belirtilen biçimlerde kullanılabilir.

a. INSERT INTO BÖLÜM(BÖLÜM_NO,BÖLÜM_ADI)


VALUES(80,'BİLGİ İŞLEM');
b. INSERT INTO BÖLÜM
VALUES(80,'BİLGİ İŞLEM',NULL);

138
Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

4.2.3 Tablolara Satır Eklerken Fonksiyonların Kullanımı


INSERT INTO deyimi içinde bazı özel değerlerin girilmesi söz konusu ise, SQL
fonksiyonları kullanılabilir.

Örnek

PERSONEL tablosuna yeni bir kayıt ekleme esnasında, GİRİŞ_TAR isimli alana o günün
tarih ve zaman bilgisini kaydetmek için şöyle bir yol izlenebilir:

INSERT INTO PERSONEL(PERSONEL_NO,ADI,GÖREVİ,ÜCRETİ,


GİRİŞ_TAR,KOMİSYON,BÖLÜM_NO)
VALUES(600,'SERAY','MEMUR',2800,
SYSDATE,NULL,30);

4.2.4 Bir Diğer Tablodan Satır Kopyalama

139
INSERT INTO deyimi ile, tabloya belirlenen değerleri içeren bir satır eklenebildiği gibi,
bir başka tablodan okunan satırlar da eklenebilir. Diğer tablodan satırları okumak için
SELECT sorgulama deyimi kullanılır. Bu durumda VALUES sözcüğü kullanılmaz.

Bir tablodan satır okuyarak, bir diğer tabloya eklemek için aşağıda belirtilen tanım
kullanılır:

INSERT INTO tablo (sütunlar)


alt sorgu;

Alt sorgudan elde edilecek sütunlar ile INSERT INTO içinde tanımlanan sütunlar karşılıklı
eşleşecektir. O nedenle, aynı veri türüne sahip olmalarına dikkat etmek gerekiyor.

Bir Tablodan Bir Başka Tabloya Kayıt Ekleme

! INSERT INTO okuna tıklayınız.

Örnek

YÖNETİCİLER isimli bir tabloya, PERSONEL tablosunda yer alan ve görevi "MÜDÜR"
veya "ŞEF" olanları seçerek eklemek istiyoruz. Amacımıza uygun deyimler şu şekilde
olacaktır:

INSERT INTO YÖNETİCİLER(PERSONEL_NO,ADI,


GÖREVİ,ÜCRET,BÖLÜM_NO)
SELECT PERSONEL_NO,ADI,
GÖREVİ,ÜCRET,BÖLÜM_NO
FROM PERSONEL
WHERE GÖREVİ='MÜDÜR'
OR GÖREVİ='ŞEF';

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

140
4.2.5 Tablodaki Verileri Güncelleme
Bir tablonun içerdiği değerler gerektiğinde değiştirilecektir. Bu amaçla UPDATE
deyiminden yararlanılır. Bu deyim şu şekilde tanımlanır:

UPDATE tablo
SET sütun1=değer1,
sütun2=değer2,…
[WHERE koşul];

141
Verilerin güncelleştirilmesi için WHERE deyimi ile bir koşul tanımlanabilir. Bu tanımın
yapılmadığı durumlarda, söz konusu tablonun tüm satırları güncelleştirilmiş olacaktır.

Örnek

Personel numarası "300" olan personelin ücretini "2500" olarak değiştirmek istiyoruz.
Bunu sağlamak için şöyle bir yol izlenir:

UPDATE PERSONEL
SET ÜCRET=2500
WHERE PERSONEL_NO=300;

Yukarıdaki sorgulamanın sonucunu görmek için linke tıklayınız

4.2.6 Bir Başka Tablodan Okunan Verilerle Güncelleme


Güncelleme işlemi, bir tablodan okunan değerlere bağlı olarak da yapılabilir. Bunun için
ikinci tablodan kayıt okuma işlemi SELECT deyimi ile gerçekleştirilir.

Bir Tablodan Okunan Verilerle Diğerini Güncelleme

142
! UPDATE okuna tıklayınız.

Örnek

Numarası "350" olan personel ile aynı göreve sahip tüm personelin bölüm numarasını,
"90" olarak değiştirmek istiyoruz. Amacımıza şu şekilde ulaşabiliriiz:

UPDATE PERSONEL
SET BÖLÜM_NO=90
WHERE GÖREVİ=(SELECT GÖREVİ
FROM PERSONEL
WHERE PERSONEL_NO=350);

4.2.7 Tablodan Satır Silme


Tabloda yer alan bir veya daha fazla sayıda satır silinebilir. Silme işlemi için DELETE
deyimi kullanılır. Bu deyim şu şekilde tanımlanıyor:

DEELETE [FROM] tablo


[WHERE koşul];

! DELETE okuna tıklayınız.

143
Örnek 1

BÖLÜM isimli tablonun tüm kayıtlarını silmek için şöyle bir yol izlenebilir:

DELETE FROM BÖLÜM;

Ancak bu tür bir silme işleminin gerçekleştirilebilmesi için, bu tablo üzerinde bütünlük
sınırlamalarının bulunmaması gerektiği unutulmamalıdır. Bu tablonun PERSONEL tablosu
arasında bütünlük ilişkilerinin tanımlandığını varsayacak olursak, bu silme işleminin
gerçekleşmeyeceğini söyleyebiliriz.

Örnek 2

BÖLÜM isimli tabloda yer alan ve bölüm kodu "60" olan bölümü silmek istiyoruz. Bunun
için DELETE deyimi şu şekilde düzenlenebilir:

DELETE FROM BÖLÜM


WHERE BÖLÜM_NO=60;

BÖLÜM ile PERSONEL arasında bütünlük sınırlamaları tanımlanmış olmasına rağmen,


amaçlanan silme işlemi gerçekleşir. Çünkü "60" numaralı bölüm BÖLÜM tablosunda
tanımlanmasına rağmen, PERSONEL tablosunda bu bölümle ilgili herhangi bir kayıt
bulunmamaktadır.

! Çalıştır okuna tıklayınız.

144
4.3 Hareket İşleme
Veri tabanlarını doğal olarak aynı anda çok sayıda kişi kullanacaktır. Kullanıcı; veri
ekleyebilir, veriyi değiştirebilir hatta silebilir. Bu değişikliklerin diğer kullanıcıları hemen
etkilemesi istenmez. Çünkü yapılan bazı işlemlerin iptal edilerek, veri tabanının önceki
hale dönüşmesi gerekebilir. Yani veri üzerinde bir değişiklik yaptığımızda, bunun
sonucunu sadece kendimiz görürüz. Gerek görülürse; bu değişikliklerin kalıcı hale
getirilerek diğer kullanıcılar tarafından da görülmesi sağlanabilir. Bu tür bir amaca
ulaşmak için hareket işleme (transaction processing) kavramını bilmek gerekir.

Verinin değiştirilmesi üzerinde etkili olan DML deyimleri çalıştırıldığında, "veri tabanı
hareketleri " (database transactions) oluşur. Başlayan bir hareket COMMIT ya da
ROLLBACK deyimleri çalıştırılıncaya dek sona ermez ve sonuçları kalıcı değildir. Bu
deyimlerden biri çalıştırıldığında veya bir başka DDL deyimi (örneğin CREATE)
çalıştırıldığında da hareket son bulur. Ayrıca bilgisayarın çalışması sona erince ya da
sistem bozulmalarında (crashes) veri tabanı hareketleri sona erecektir.

Veri tabanı hareketleri INSERT, UPDATE ve DELETE gibi deyimlerin çalıştırılması


sonucunda başlar.

4.3.1 Hareketin Sona Erdirilmesi

145
Veri tabanı hareketlerinin başlaması için INSERT,UPDATE veya DELETE deyimlerinden
birinin çalıştırılması yeterlidir. Ancak bir kullanıcının bu şekilde yaptığı bir işlemin sonucu
diğer kullanıcıyı etkilemez. Bu şekilde başlayan bir işlemi sona erdirmek için COMMIT
kullanılır.

Örnek

Veri tabanı kullanıcılarından birinin aşağıdaki deyimi çalıştırdığını varsayalım.

UPDATE PERSONEL
SET BÖLÜM_NO=10
WHERE PERSONEL_NO=300;

Bu deyimin çalıştırılması ardından, "300" numaralı personelin bölüm numarası "10"


olarak değiştirilir. Söz konusu değişiklik sadece bu deyimi çalıştıran kullanıcı için
yapılmıştır. Veri tabanına ulaşan diğer kullanıcılar bu değişikliğin sonucunu görmezler.
Çünkü kullanıcının yarattığı hareket sona ermemiştir. Aynı kullanıcı bu kez,

COMMIT; deyimini çalıştıracak olursa, yaptığı tüm değişiklikler kalıcı hale gelir ve diğer
veri tabanı kullanıcıları da bu değişikliği algılamış olurlar.

4.3.2 Değişikliklerin Geri Alınması


Veri tabanı üzerinde bir kullanıcı tarafından gerçekleştirilen değişikliğin kalıcı hale gelmesi
için COMMIT deyiminden yararlanıyoruz. Bu deyim çalıştırılmadığı sürece, tüm DML
deyimlerinin etkileri geri alınabilir. Yani değişiklikler iptal edilebilir. Böyle bir amaca
ulaşmak için,

ROLLBACK;

deyimi kullanılır.

Örnek

PERSONEL tablosunun tüm kayıtlarını silmek için,

146
DELETE FROM PERSONEL;

Deyiminin çalıştırıldığını varsayalım. Bu deyim çalıştırıldığında, bu deyimi çalıştıran


kullanıcı için PERSONEL tablosunun tüm kayıtları silinmiştir. Henüz COMMIT deyimi
çalıştırılmadığı için diğer kullanıcılar bu işlemden etkilenmez ve bu durumda, silinen
kayıtları geri alma olanağı bulunmaktadır. Silme işlemini iptal etmek için,

ROLLBACK; deyimi çalıştırılırsa, PERSONEL tablosunun eski haline dönüştüğü görülür.

147
148
149
150
151
152
153
PL/SQL’E GİRİŞ

Bu bölümde;

• PL/SQL ile Veri Tabanı Programlama


• Blok Türleri
• PL/SQL Programlarının Yapısı
• PL/SQL Programlarının Görünümü
• PL/SQL Bloklarının Çalıştırılması
• Karakter Kümesi
• Değişkenler ve Değişmezler
• SQL Deyimlerinin PL/SQL İçinde Kullanımı
• Bağlı Değişkenler
• Değerlerin Görüntülenmesi için Bir Diğer Yol
• Bildirimler Bölümü
• Veri Türleri
• İfadeler
• İşleçler
• Açıklama Satırları

anlatılmaktadır.

Bölüm Hedefi
Bu bölümde aşağıda sıralanan konular ele alınarak
incelenecektir:

• PL/SQL ile veri tabanı programlama


• Karakter kümesi
• Değişkenler ve değişmezler
• Bildirimler bölümü
• Veri türleri
• İfadeler
• İşleçler

• Açıklama satırları

5.1 PL/SQL İle Veri Tabanı Programlama


Bu bölümde bir veri tabanı programlama dili olarak değerlendirilen PL/SQL dili
anlatılacaktır. PL/SQL blok yapılı bir programlama dilidir. Yordamsal (Procedural)
programlama dilleri arasında değerlendirilebilir. PL/SQL programlama dili sadece ORACLE
veri tabanlarında kullanılabilir. PL/SQL Oracle üzerinde iki farklı ortamda yer
alabilmektedir. Bunlar aşağıda verildiği gibidir.

154
• Oracle veri tabanı sunucusu
• Oracle yazılım geliştirme araçları

Bu iki ortam birbirinden bağımsız olarak değerlendirilebilir. PL/SQL programları yada bir
başka deyişle PL/SQL blokları doğrudan veri tabanı üzerinde tanımlanarak çalıştırılabilir.
Bunun dışında, söz konusu PL/SQL programları bir uygulama geliştirme ortamında,
örneğin “Oracle Developer” isimli yazılım geliştirme araçları üzerinde tanımlanarak
kullanılabilir.

PL/SQL blokları PL/SQL motoru üzerinde çalıştırılır. PL/SQL motoru PL/SQL programlarını
çalıştıran bir ortamdır. PL/SQL programları SQL deyimlerini ve bunlara ek olarak bazı özel
deyimleri içeren bir programlama dilidir. PL/SQL motoru şekil üzerinde görüldüğü biçimde
bu programları yorumlayarak, istekleri SQL komutları biçiminde Oracle veri tabanına
gönderir.

5.2 Blok Türleri


PL/SQL bir programlama dilidir ve programlar bloklardan oluşur. Çeşitli blok türleri vardır.
PL/SQL de aşağıda sıralanan bloklardan söz edilebilir:

• Anonim bloklar
• Yordamlar (procedures)
• Fonksiyonlar (functions)

Sıralanan bu blok yapılarından öncelikle anonim blok yapılarını kullanacağız. Dersimizin


sonraki konularında diğer blok türlerini de ele alarak inceleyeceğiz.

! PL/SQL Blok Türlerini görmek için Devam düğmesine tıklayınız.

155
5.3 PL/SQL Programlarının Yapısı
PL/SQL programları bloklardan oluşur. Bu bloklar ayrı ayrı olabileceği gibi, içiçe blokların
oluşturulması da mümkündür. Bir blok yada alt blok mantıksal bildirimler (declaration)
ve onu takip eden PL/SQL deyimlerinden oluşmaktadır. Bir PL/SQL bloğu aşağıda
belirtildiği biçimde tanımlanmaktadır:

156
157
5.4 PL/SQL Programlarının Görünümü
Bir SQL bloğu DECLARE, BEGIN ve EXCEPTION bölümlerinden oluşmaktadır. Yandaki örnek
bir PL/SQL programının görünümü hakkında bir fikir vermektedir. Bu blok içinde yer alan
deyimleri sonraki bölümlerimizde ele alarak inceleyeceğiz.

5.5 PL/SQL Bloklarının Çalıştırılması


PL/SQL bloklarının sadece ORACLE veri tabanlarında çalıştırılabildiği unutulmamalıdır. Bu
bloklar iki türlü çalıştırılabilir. Birincisi bir uygulama programı içinden olabilir. Örneğin
Oracle Developer isimli yazılım geliştirme ortamında hazırlanan programlarda bu PL/SQL
blokları tanımlanarak çalıştırılabilir.

PL/SQL bloklarını çalıştırmanın bir diğer yolu, Oracle’ın SQL*Plus ortamınının


kullanılmasıdır. Oracle kullanıcılara, hem SQL deyimlerinin hem de PL/SQL bloklarının
doğrudan çalıştırılabilmesi için uygun bir ortam sağlamaktadır. SQL*Plus programı söz
konusu komutların girilmesine ve çalıştırılmasına yönelik bir arayüz sunmaktadır.

158
5.5.1 SQL*Plus Arayüzüne Giriş
SQL*Plus arayüzüne ulaşabilmek için, öncelikle kullanıcının veri tabanına kendisini
tanıtması gerekmektedir. Bu kullanıcı daha önce veri tabanında yaratılmış olması
zorunludur. Örneğin, kulanıcı adının test şifresinin de test olduğunu varsayalım. Şu anda
Oracle’ın tek kişilik sürümünde varsayıyoruz. Yani veri tabanı şu anda aynı bilgisayar
üzerindedir. O nedenle üçüncü satırdaki ana bilgisayar ile ilgili tanım yapılmaz.

5.5.2 SQL*Plus Arayüzünün Görünümü


Kullanıcı adı ve parolası doğru biçimde girildikten sonra SQL*Plus arayüzüne ulaşılır. Bu
arayüzün başlangıçtaki görünümü aşağıdaki şekil üzerinde görüldüğü gibidir. Arayüz
aslında, SQL deyimlerinin girildiği ve çalıştırıldığı bir ortamdır. Komutlar,

SQL>

ifadesinin hemen ardından kaydedilir. Bu arayüzü kapatmak için, menü üzerindeki Dosya
seçeneğinin Çıkış alt seçeneği kullanılabilir. Ancak,

159
SQL> EXIT;

biçiminde bir tanım yapılarak da arayüz terkedilebilir.

5.5.3 SQL Deyimleri Nasıl Çalıştırılır ?


Bir SQL deyimi SQL> ifadesi ardından yazılır. Doğal olarak SQL deyimlerinin sonuna “;”
işaretinin kaydedilmesi gerekiyor. Bu şekilde SQL deyiminin yazılması işlemi sona
erecektir. SQL*Plus, SQL deyiminin sonunu bu şekilde algıladıktan sonra hemen
çalışmaya başlayarak sonuçları görüntüler. Örneğin, BOLUM isimli tablonun tüm içeriğini
listelemek için SQL deyimi şu şekilde tanımlanmaktadır:

SQL> SELECT * FROM bolum;

Bu program çalıştırıldığında aşağıdaki şekil üzerinde görüldüğü biçimde bir sonuç


görüntülenir.

! Sorgulamanın sonucunu görmek için "Çalıştır" düğmesine basınız.

160
Bir SQL deyimi veya bir PL/SQL bloğu SQL*Plus ortamında bu şekilde yazıldıktan sonra
çalıştırılırsa, bu deyim bir ara belleğe otomatik olarak kaydedilir. O halde bu deyimi bir
sonraki adımda çalıştırmak gerektiğinde yeniden yazmaya gerek yoktur. Onun yerine,

SQL> RUN;

veya kısaca,

SQL> /

tanımı kullanılır. Sonuç aynı biçimde elde edilir.

5.5.4 SQL ve PL/SQL Dosyalarının Yaratılması ve


Çalıştırılması
SQL deyimlerinin ve PL/SQL bloklarının çalıştırılması için bir başka yol daha vardır. Bunun
için söz konusu deyim yada bloklar belirlenen bir isimle disk üzerinde saklanır ve
gerektiğinde çağrılarak çalıştırılır. Bir SQL deyimini veya PL/SQL bloğunu saklamak için en
basit yol, Dosya menüsünün Kaydet seçeneğini kullanmaktır.

İkinci yol olarak, SQL*Plus’un SAVE komutu kullanılır. Bu şekilde yapılan saklama
işlemleri sonucunda, sonu .sql ile biten bir dosya yaratılmış olur. Örneğin test isimli bir
SQL dosyası şu şekilde oluşturulabilir:

SQL> SAVE test;

161
Bir dosya yaratıldıktan sonra, doğal olarak gerektiğinde çağrılarak çalıştırılacaktır. Var
olan bir SQL dosyasını çağırmak için SQL*Plus’un START komutu kullanılır. Örneğin, daha
önce yaratılmış bir SQL dosyası şu şekilde çağrılarak çalıştırılabilir:

SQL> START C:\TEST\TEST;

5.6 Karakter Kümesi


Bir PL/SQL programında belirli bazı karakterler kullanılabilir. Bu karakterler dışında
herhangi bir karakter yer alırsa, program çalışmaz. PL/SQL programlarında aşağıda
sıralanan karakterler yer alabilir:

! PL/SQL programları büyük harf-küçük harf ayrımına karşı duyarlı değildir. Yani bir
deyim ya da değişken istenirse küçük, istenirse büyük harflerle yazılabilir. Programın
işleyişi bundan etkilenmez.

5.7 Değişkenler ve Değişmezler


PL/SQL yordamlarında, diğer tüm programlama dillerinde olduğu gibi, değişkenler veya
değişmezler kullanılabilir. Bir değişken yada sabitin kullanılabilmesi için, öncelikle
bildirimler bölümünde, yani DECLARE bölümü içinde tanımlanmış olması gerekiyor.
Örneğin, ADI ve MUSTERI_NO isimli iki değişkeni programa tanıtmak için aşağıdaki tanım
yapılır:

DECLARE
adı VARCHAR2(20);
musteri_no NUMBER(5);

Bir değişken bu şekilde tanımlandıktan sonra, program içinde bu değişkene belirli bir
değer atanabilir, yani bir değer yerleştirilebilir. Bir değişkene bir değeri atamak için “:=”
işareti kullanılır. Örneğin, musteri_no değişkenine 196 değerini atamak için şöyle bir
tanım yapılır:

musteri_no := 196;

Bir değişkene program içinde bu şekilde bir atama yapılabileceği gibi, gerektiğinde
bildirimler bölümünde bir başlangıç değer atanabilir. Örneğin, musteri_no değişkenine
aşağıda görüldüğü gibi, bildirimler bölümünde bir değer atanabilir.

162
DECLARE
adı VARCHAR2(20);
musteri_no NUMBER(5) :=196;

Bu tanımdan şu anlaşılmaktadır: Program içinde adı ve musteri_no isimli iki değişken


kullanılacaktır. adı isimli değişkenin veri türü VARCHAR2 ve uzunluğu 20 karakter olarak
belirlenmiştir. musteri_no isimli değişken ise 5 uzunluklu bir NUMBER veri türüne sahiptir.
Veri türlerini daha ayrıntılı biçimde ele alarak inceleyeceğiz.

PL/SQL programlarında değişkenler yanı sıra değişmezler (sabitler) de tanımlanabilir.


Değişmezler, adından da anlaşılabileceği gibi program içinde değeri değiştirilemeyen
olanaklardır. Değişmezleri tanımlamak için CONSTANT anahtar kelimesi kullanılır. Örneğin,
PI isimli bir sabit şu şekilde tanımlanabilir:

DECLARE
PI CONSTANT REAL :=3.14159;

Buradan şu anlaşılmaktadır. PI isimli değişmez program içinde kullanılacaktır. Bu


değişmezin değeri 3.14159 dur ve veri türü REAL olarak belirlenmiştir. PL/SQL blokları
içinde bu değer değiştirilmeye çalışılmaz.

! Örnek içerisinde bir grup değişken ve sabit tanımı yapılmaktadır.

Örneği görmek için linke tıklayınız

5.8 SQL Deyimlerinin PL/SQL İçinde Kullanımı


PL/SQL blokları içinde BEGIN bloğunda amaca uygun deyimler yer almaktadır. Bu
deyimlerin bir kısmı PL/SQL’e özgü deyimler ve kavramlar olmasına karşılık; bazıları
bildiğimiz SQL deyimleridir. SQL deyimlerinin neler olduğunu ve nasıl çalıştığını önceki
konulardan biliyoruz. SQL’in pek çok deyimi ve fonksiyonları PL/SQL içinde de aynen
çalışır.

163
PL/SQL blokları DDL deyimlerini desteklemez. Bu deyimler, bildiğiniz gibi, veri tabanı
içindeki tabloları yaratma ve yok etme ya da özelliklerini değiştirme ile ilgilidir. O nedenle
CREATE TABLE, ALTER TABLE, DROP TABLE ve bunun gibi DDL deyimlerini PL/SQL blokları
içinde kullanamayız.

5.8.1 SELECT Deyiminin Kullanılması

PL/SQL blokları içinde SELECT deyimi kullanılabilir. Bunun için, SQL deyimlerinin aşağıda
belirtilen yapıya sahip olması gerekmektedir.

SELECT sütun isimleri


INTO (değişken adı veya kayıt adı}
FROM tablo adı
WHERE koşul;

! Burada INTO anahtar kelimesine dikkat etmek gerekmektedir. Bu kelime, seçilen sütun
değerlerinin hangi değişkene ya da kayıta aktarılacağını belirlemektedir. Sözü edilen
değişkenler PL/SQL bloğununun DECLARE bölümünde tanımlanmış olmalıdır.

! SELECT deyiminin kullanımında dikkat edilecek önemli bir nokta daha bulunmaktadır.
PL/SQL blokları içinde yer alacak SELECT sorgularında sadece bir satırın döndürülmesi
gerektiği unutulmamalıdır. Her bir SELECT deyimi “;” işareti ile son bulmalıdır.

Örnek

Veri tabanında yer alan personel isimli tablodan personel numarası 101 olan personeli
seçerek adını v_adi isimli bir değişken içine yerleştirmek istiyoruz.

Bu amaçla düzenlenmiş olan PL/SQL bloğunu görmek için linke tıklayınız

DECLARE
v_adi VARCHAR2(10) ;
BEGIN
SELECT adi
INTO v_adi
FROM personel
WHERE personel_no=101;

164

END;

5.8.2 DML Deyimlerinin Kullanılması


SQL’in DML deyimlerini kullanarak tablolara satır ekleme, güncelleme ve satır silme gibi
işlemleri yerine getirmek mümkündür. Bunun için SQL’in aşağıda belirtilen deyimlerine
başvurulur.

Örnek 1

Veri tabanında yer alan personel isimli tabloya bir kayıt eklemek istiyoruz.

Amacımıza uygun olarak düzenlenen PL/SQL bloğunu görmek için linke tıklayınız

BEGIN
INSERT INTO personel(personel_no,adi,giris_tar,ucret)
VALUES(101,'BURAK','15/03/1970',7000)
END;

Örnek 2

Veri tabanında yer alan personel isimli tabloda, personel numarası 101 olan personelin
ücretine %25 zam yapmak istiyoruz.

İlgili personelin ücret bilgisinin nasıl güncelleştirildiğini görmek için linke tıklayınız

DECLARE
v_ucret NUMBER :=1.25;

165
BEGIN
UPDATE personel
SET ucret=ucret*v_ucret
WHERE personel_no=101;
END;

Örnek 3

personel tablosunda, personel numarası 101 olan personeli silmek istiyoruz.

Bu amaçla hazırlanan PL/SQL bloğunu görmek için linke tıklayınız

DECLARE
v_personel_no personel.personel_no%TYPE :=101;
BEGIN
DELETE FROM personel
WHERE personel_no=v_personel_no;
END;

5.8.3 Hareket İşleme Deyimlerinin Kullanılması


Veri tabanı hareketlerinin başlaması için INSERT,UPDATE veya DELETE deyimlerinden
birinin çalıştırılması yeterlidir. Bunu biliyoruz. Bu şekilde başlayan bir işlemi sona
erdirmek, yani değişiklikleri kalıcı hale getirmek ve sonuçları diğer kullanıcıların da
görmesini sağlamak için COMMIT deyimini kullanıyoruz. Değişiklikleri geri almak için ise
ROLLBACK deyimini tercih ediyoruz. Bu deyimleri PL/SQL blokları içinde de aynen
kullanmak mümkündür.

Örnek

personel tablosunda bir güncelleme yaptıktan sonra, bu sonucun diğer kullanıcıları da


etkilemesini sağlamak için PL/SQL bloğuna COMMIT deyimini ekliyoruz.

Bu amaçla hazırlanan PL/SQL bloğunu görmek için linke tıklayınız

DECLARE
v_ucret NUMBER :=1.25;
BEGIN
UPDATE personel
SET ucret=ucret*v_ucret
WHERE personel_no=101;
COMMIT;
END;
/

5.9 Bağlı Değişkenler

166
Bazı değişkenlerin bildirimi bazı durumlarda PL/SQL blokları içinde tanımlanmaz. Bu
değişkenler PL/SQL bloğu dışında bir ortamda tanımlanır. Örneğin, SQL*Plus ortamında
daha önce tanımlanmış bir değişken PL/SQL içinde doğrudan kullanılabilir. Bunun için
değişkenin başına (:) işareti yerleştirilir. Bir bağlı değişken (bind variable) şu şekilde
tanımlanır:

VARIABLE değişkenin adı veri türü

O halde bir bağlı değişkeni, yani PL/SQL bloğu dışında bir değişkeni tanımlamak için,
VARIABLE deyimi içinde önce ilgili değişkenin adı, ardından o değişkenin veri türü
belirlenir. Bir bağlı değişkenin içerdiği değeri görüntülemek için PRINT komutu kullanılır.
Bu deyim şu şekilde tanımlanır:

PRINT değişkenin adı;

Örnek 1

Aşağıdaki PL/SQL deyimlerini göz önüne alalım. PL/SQL bloğu başında SQL*Plus’un
VARIABLE komutu yardımıyla g_adi değişkenini tanımlıyoruz.

SQL> VARIABLE g_adi VARCHAR2(10);


SQL> DECLARE
v_adi VARCHAR2(10) ;
BEGIN
SELECT adi
INTO v_adi
FROM personel
WHERE personel_no=101;
-- Bağlı değişkene değer aktarılıyor..
:g_adi := v_adi ;
END;
/

Yazdığımız PL/SQL bloğu içerisinde yapılan tanımların açıklamalarını görmek için


linke tıklayınız

Yapılan tanımları tek tek açıklamak istiyoruz: Birinci satırdaki,

SQL> VARIABLE g_adi VARCHAR2(10);

ifadeleri bir g_adi isimli değişkeni tanımlamaktadır. Bu değişken PL/SQL bloğu tarafından
kullanılmaktadır. PL/SQL bloğunun kullandığı değişken DECLARE bölümü içinde
tanımlanmaktadır:

DECLARE
v_adi VARCHAR2(10) ;

Bloğun işlem kısmı BEGIN ile başlamaktadır. Bu bölümde bir SELECT deyimi
çalıştırılmaktadır. Söz konusu deyim, personel tablosunda personel numarası 101 olan
personelin adını seçmektedir.

BEGIN

167
SELECT adi
INTO v_adi
FROM personel
WHERE personel_no=101;

Blok içindeki SELECT deyimi çalıştığında, seçilen personel adı v_adi isimli değişken içine
yerleşecektir. Bu sonucu kullanabilmek için bir dış değişkene aktarıyoruz. Sözü edilen dış
değişkeni VARIABLE deyimi ile en başta tanımlamıştık. v_adi değişkeninin içerdiği değer
g_adi değişkeni içine şu şekilde aktarılmaktadır:

:g_adi := v_adi ;

Artık g_adi isimli değişkenin içeriğini görüntüleyebiliriz. Bunun için SQL*Plus ortamında
PRINT komutu şu şekilde kullanılır.

SQL> PRINT g_adi;

! PRINT komutu g_adi isimli değişkenin içeriğini görüntülemek için çalıştırıldığında


aşağıda görüldüğü biçimde bir sonuç elde edilir:

G_ADI
--------------------------------
BURAK

Örnek 2

Bir x bağlı değişkenini tanımladıktan sonra bu değişkene PL/SQL bloğu yardımıyla 100
değerini atamak istiyoruz. Bu işlemin ardından x değişkeni içeriği görüntülenecektir.

Bu amaçla hazırlanan PL/SQL bloğunu görmek için linke tıklayınız

SQL> VARIABLE x NUMBER;


SQL> BEGIN
2 :x:=100;
3 END;
4 /

! Son satırda “/” işareti yer aldığı için bu yordam çalışmaya başlar. Bu PL/SQL bloğu
aşağıda görülen sonuç elde edilir:

SQL> PRINT X;
X
----------
100

5.10 Değerlerin Görüntülenmesi İçin Bir Diğer Yol


Önceki konuda görüldüğü gibi, bir bağlı değişkenin değerini PRINT komutu ile
görüntüleyebiliyoruz. Bu yöntem yerine, PL/SQL bloğu içinde bir değişkenin değerini ya
da herhangi bir mesajı doğrudan görüntülemek için bir başka yol izlenebilir. Böyle bir

168
amaca ulaşmak için, DBMS_OUTPUT.PUT_LINE()paketi kullanılır. Bu paket şu şekilde
tanımlanır:

DBMS_OUTPUT.PUT_LINE(mesaj veya değişken);

Bu paketin SQL*Plus ortamında geçerli olabilmesi için öncelikle,

SQL> SET SERVEROUTPUT ON;

komutunun çalıştırılmış olması gerekmektedir. Aksi takdirde söz konusu paket etkili
olmayacaktır.

Örnek

Veri tabanındaki personel isimli tablodan 101 numaralı personelin adını bulacağız. Bunun
için, öncelikle PL/SQL bloğunun SQL*Plus ortamında istenen sonucu verebilmesi için
aşağıda görüldüğü biçimde bir tanım yapılmalıdır:

SQL> SET SERVEROUTPUT ON;

Bu tanımın ardından aşağıdaki PL/SQL bloğunun çalıştırılması söz konusudur:

DECLARE
v_adi VARCHAR2(10) ;
BEGIN
SELECT personel_no, adi
INTO v_no, v_adi
FROM personel
WHERE personel_no=101;
-- Sonuç görüntüleniyor …
DBMS_OUTPUT.PUT_LINE (v_adi);
END;

Bu PL/SQL bloğu çalıştırıldığında SQL*Plus ekranında aşağıda belirtilen sonuç


görüntülenir:

BURAK

Bu blok çalıştırıldığında sadece personelin adı görüntülenir. Eğer personelin numarası da


isminin sol tarafında görüntülenmek isteniyorsa, PL/SQL bloğu farklı bir biçimde yazılır.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız

DECLARE
v_no VARCHAR2(10) ;
v_adi VARCHAR2(10) ;
BEGIN
SELECT personel_no, adi
INTO v_no, v_adi
FROM personel
WHERE personel_no=101;

169
-- Sonuç görüntüleniyor …
DBMS_OUTPUT.PUT_LINE (v_no ||' ' ||v_adi);
END;

Yukarıdaki blok çalıştırıldığında ise şu şekilde bir sonuç elde edilir:

101 BURAK

5.11 Bildirimler Bölümü


Bildirimlerin DECLARE ile başlayan bölümde tanımlandığını biliyoruz. Bu bölümde değişken
ve değişmezler tanımlanmaktadır. Ancak değişkenler basit biçimde tanımlanabildiği gibi,
ek bazı özelliklere de yer verilebilir. Bu amaçla aşağıda belirtilen özellikler üzerinde
duracağız.

5.11.1 Varsayılan Değerler


Bir değişkene DECLARE bölümünde “:=” ile belirli bir değer atayabiliyoruz. Bunun yerine,
bir değişkene, herhangi bir atama yapılmadığı sürece geçerli olmasını sağlamak üzere
varsayılan değer atanabilir. Bunun için DEFAULT anahtar kelimesi kullanılır.

Örnek

Aşağıdaki bildirimi göz önüne alalım:

DECLARE

170
fis_no NUMBER(5) :=0;
durum BOOLEAN := FALSE;

Bu tanımdan şu anlaşılmaktadır: fis_no isimli NUMBER veri türüne sahip bir değişkene 0
başlangıç değeri; durum isimli BOOLEAN veri türüne sahip bir değişkene FALSE değeri
atanmaktadır. Bunun yerine, aynı anlamı taşımak üzere şu şekilde bir tanım yapılabilir:

DECLARE
fis_no NUMBER DEFAULT 0;
durum BOOLIAN DEFAULT FALSE;

5.11.2 NULL Değerlerin Denetlenmesi

Normal olarak bir değişken NULL değerler içerebilir. Bir değişkenin NULL değerler
içermesini önlemek gerekebilir. Bu tür bir sınırlama koyabilmek için, değişken
bildirimlerine NOT NULL anahtar kelimeleri eklenebilir.

Örnek

Aşağıdaki bildirimi göz önüne alalım:

DECLARE
fis_no NUMBER(5) NOT NULL :=0;
durum BOOLEAN := FALSE;

Bu tanımdan şu anlaşılmaktadır: fis_no isimli NUMBER veri türüne sahip bir değişkene 0
başlangıç değeri atanmaktadır. Söz konusu değişkene daha sonra bir başka değer
atanabilir. Ancak hiçbir zaman NULL değer atanamaz, yani boş bırakılamaz.

5.11.3 %TYPE Kullanımı

Bir değişkenin sahip olduğu veri türünü bir başka değişken için de geçerli kılınabilir. Böyle
bir amaca ulaşabilmek için %TYPE anahtar kelimesinden yararlanılır. Bu anahtar kelime şu
şekilde kullanılır:

171
değişken%TYPE

Örnek 1

Bir değişkenin aşağıda gösterildiği biçimde tanımlandığını varsayalım:

DECLARE
tutar REAL(9,2);

Bir başka değişkenimiz bolum_tutar olsun. Bu yeni değişkenin veri türünün de


REAL(9,2)olduğunu kabul edelim. Bu durumda, Aşağıda görüldüğü biçimde bir tanım
yapılabilir:

DECLARE
tutar REAL(9,2);
bolum_tutar REAL(9,2);

Bu tanım yerine %TYPE kullanarak şu şekilde bir bildirim yapılabilir:

DECLARE
tutar REAL(9,2);
bolum_tutar TUTAR%TYPE;

Örnek 2

Aşağıdaki PL/SQL bloğunu göz önüne alalım. DECLARE bölümünde tanımlanan değişken,
personel tablosunun ucret isimli sütunu ile ilişkilidir. O nedenle, değişken türünü
belirlerken %TYPE ifadesinden yararlandık.

Bu amaçla düzenlenmiş olan PL/SQL bloğunu görmek için linke tıklayınız

DECLARE
v_ucret personel.ucret%TYPE :=1.25;
BEGIN

172
UPDATE personel
SET ucret=ucret*v_ucret
WHERE personel_no=101;
END;

! Bu tanımdan şu anlaşılmaktadır: v_ucret değişkeni, personel tablosunun ucret isimli


sütunu ile aynı veri türüne sahiptir. O halde ayrıca veri türünü belirtmeye gerek yoktur.

5.11.4 %ROWTYPE İle Kayıt Türünün Belirlenmesi

PL/SQL bildirimler bölümünde, bir tablo içindeki satırın kayıt türünü simgelemek üzere
%ROWTYPE anahtar kelimesi kullanılır. Burada sözü edilen kayıt, bir tablodan veya bir
imleç (cursor) yardımıyla elde edilebilir. İmleçleri ve kullanım biçimlerini daha sonraki
derslerimizde ayrıntılı olarak ele alarak inceleyeceğiz.

İmleç, kısaca söz etmek gerekirse, SQL deyimlerini çalıştırmak için gereksinim duyulan
bellek alanlarıdır. Önceki konularımızda ayrıntılı biçimde öğrendiğimiz SQL’in SELECT
deyimi ile bir tablodan okunan sonuçlar, bir imleç üzerine yerleştirilir ve imleç üzerinde
bir kayıt kümesi oluşturulur. PL/SQL deyimleri yardımıyla bu kayıtlar işleme tabi tutulur.

Örnek

Aşağıdaki bildirimi göz önüne alalım:

DECLARE
pers_kayit personel%ROWTYPE
CURSOR c1 IS SELECT adi_soyadi, numara, bölüm_no
FROM personel;
bolum_kayit c1%ROWTYPE;

Burada iki kayıt tanımı yapılmaktadır. Bunlardan birincisi ,

pers_kayit personel%ROWTYPE

173
tanımıdır. Bu tanım, personel isimli bir tablodan okunan her bir kayıdı pers_kayit
olarak belirlemektedir. Yani tablonun her bir satırı pers_kayit adıyla saklanmaktadır.
İkinci %ROWTYPE tanımı ise,

bolum_kayit c1%ROWTYPE;

biçimdedir. Bu tanım, c1 imlecinden getirilen kayıtların saklandığı bolum_kayit isimli


kayıdı belirlemektedir. Tanımlar arasında yer alan,

CURSOR c1 IS SELECT adi_soyadi, numara, bölüm_no


FROM personel;

satırı ise, bir imleci belirlemektedir. Buna göre, personel tablosundan SELECT
deyimi ile seçilen sonuçlar için c1 imleci atanmaktadır. SELECT deyiminin nasıl
kullanıldığını ve yazılan ifadelerin ne anlama geldiğini önceki derslerden
biliyorsunuz.

5.12 Veri Türleri


SQL ortamında kullanılan veri türleri PL/SQL ortamında da aynen geçerlidir. Aşağıdaki
tablo bu veri türlerinin en çok kullanılanlarını içermektedir.

174
Veri türü Anlamı

VARCHAR2(boyut) Değişken uzunluklu karakter verileri ifade eder.


Tanım içindeki boyut ifadesi, sütunun alabileceği en
fazla karakter sayısını sınırlar. Varsayılan değeri 1, en
uzun boyutu ise 4000 karakterdir.

CHAR(boyut) Belirlenen boyuttaki sabit uzunluklu karakter verileri


ifade etmekte kullanılır. Varsayılan değer 1, en uzun
boyutu ise 2000 karakterdir.

NUMBER(p,s) Ondalıklı sayısal değerlerin ifade edilmesinde


kullanılır. Tanımda p ondalık hanelerin toplam
sayısını, s ise ondalık noktasının sağındaki hanelerin
sayısını belirler. Burada p değeri 1 ile 38, s ise -84 ile
127 arasında bir değer olabilir.

DATE Tarih ve zaman verilerini ifade etmekte kullanılır.

LONG Değişken uzunluklu karakter veriyi ifade eder. Boyutu


2 gigabayt kadar olabilir.

CLOB 4 gigabayta kadar karakter verileri ifade eder.

RAW(boyut) Boyutu belirlenmiş ikili (binary) verileri ifade etmekte


kullanılır. En büyük boyutu 2000 olabilir.

LONG RAW 2 gigabayta kadar boyuta sahip değişken uzunluklu


ikili verileri ifade etmekte kullanılır.

BLOB 4 gigabayta kadar ikili verileri ifade eder.

BFILE Bir dış dosyada saklanan ikili verileri belirtir. 4


gigabayt kadar bir büyüklüğe sahip olabilir.

175
Örnek

Aşağıdaki bildirimler bölümünde çeşitli veri türleri tanımlanmaktadır:

DECLARE
adi VARCHAR2(20);
personel_no BUNBER(8);
ucret NUMBER(7,2);
adres VARCHAR2(200);
dogum_tar DATE;

5.13 İfadeler
Değişkenlere doğrudan bir değerin atanması yerine, bir ifadenin atanması da söz konusu
olabilir. Örneğin bir aritmetik ifade tanımlanarak sonucunun atanması mümkündür.
Üstelik mantıksal ifadeler de tanımlanarak sonucun doğru ya da yanlış olma durumuna
göre TRUE ya da FALSE değerleri atanabilecektir.

Örnek

Aşağıdaki ifadeleri inceleyiniz.

sayac := sayac+1;
ssk_primi := brut_ucret*oran;
zamli_ucret := aylik_ucret*1.45;

Mantıksal değerlerin atanması ise

durum := calisilan_saat>225;

Bu örneğe göre, calisilan_saat değişkeninin içerdiği değer 225 sayısal değerinden


büyük ise, yani belirtilen koşul sağlanıyorsa durum değişkeninin değeri TRUE olacaktır.

176
5.14 İşleçler
Aritmetik işlemler başta olmak üzere, büyüklüklerin karşılaştırılması ve mantıksal
karşılaştırmaların yapılmasını sağlamak için işleç (operatör) adı verilen simgelere
başvurulur. PL/SQL programlarında en çok aşağıda belirtilen işleçler kullanılmaktadır.

5.14.1 Aritmetik İşleçler


Toplama, çıkarma, çarpma ve bölme işlemlerini yapmaya yönelik işleçler aritmetik
işleçler olarak bilinir. Bu işleçler belirli bir sıraya göre işlem görürler. Yan taraftaki tablo
üzerinde aritmetik işleçleri tanımlıyoruz.

Bölme işlemlerinde paydanın sıfır değere sahip olmamasına dikkat etmek gerekiyor.

Aritmetik İşleçleri ve anlamlarını tekrar görmek için TEKRAR düğmesine


tıklayınız.

Örnek

Aşağıdaki satırları inceleyiniz. Burada üç ifade yer almaktadır. Bu ifadeler içinde aritmetik
işleçlerin kullanıldığını görüyoruz:

deger := deger + sonuc;


zam := ucret*zam;
sonuc_1 := yıllık_ucret/ 12;

5.14.2 Karşılaştırma İşleçleri

177
Bu işleçler iki sayısal değeri ya da iki karakteri karşılaştırmak amacıyla kullanılır. Söz
konusu bu işleçler çoğunlukla program içindeki karşılaştırma deyimleri ile birlikte
kullanılır. Karşılaştırma işleçlerini yandaki tablo üzerinde sunuyoruz.

! Karşılaştırma İşleçlerini ve anlamlarını tekrar görmek için 'TEKRAR'


düğmesine tıklayınız.

5.14.3 Mantıksal İşleçler


Mantıksal işleçler, iki veya daha fazla sayıdaki koşulun birlikte sınanması amacıyla
kullanılırlar. Bu işleçleri aşağıdaki tablo üzerinde veriyoruz:

İki veya daha fazla koşul, doğruluk değerleri göz önüne alınarak birlikte değerlendirilir.
Koşullardan birincisine x , ikincisine ise y adını verelim. Bu iki koşulun değil, ve ile veya
işleçlerine göre doğruluk tablosu aşağıda verildiği gibidir.

178
Program içinde birden fazla koşul birlikte kullanılıyorsa, yukarıdaki tabloda yer alan
doğruluk değerleri kullanılır.

5.15 Açıklama Satırları


PL/SQL programları arasına açıklama satırları eklenebilir. Bu satırlar işlem görmez.
Sadece programın bazı bölümlerini açıklamak amacıyla kullanılır. Yani program
satırlarının belgelenmesini sağlar.

Açıklama satırını PL/SQL programı içine yerleştirmek için, satırın baş tarafına “--“
işaretleri kaydedilir. Örneğin şu şekilde bir açıklama satırı oluşturulabilir:

--Net ücret hesabı yapılıyor..

Eğer açıklama satırı birden fazla ise, her satırın başına bu işaretleri kaydetmek yerine,
açıklama satırının başlangıcına “/*” işareti, sonuna ise “*/” işareti kaydedilir. Örnek
olarak aşağıdaki tanım yapılabilir.

/* Net ücret hesabı yapılıyor.. Bunun


için aşağıda belirtilen hesaplamlar gerçekleştirilir */

179
180
181
182
183
184
PROGRAM DENETİMİ

Bu bölümde;

• Koşullu Denetim-IF Deyimi


• Döngü İşlemleri
• GOTO Deyimi ile Bir Etikete Sapılması

anlatılmaktadır.

Bölüm Hedefi
Bu bölümde aşağıda sıralanan konular ele alınarak
incelenecektir:

• Koşullu denetim işlemleri


• IF deyiminin kullanımı
• Sonsuz döngüler
• Sonsuz döngüden çıkış
• Koşullu döngüler
• Belirli sayıda tekrarlar
• Değişkenler ve değişmezler
• Döngü etiketlerinin kullanımı

• GOTO deyiminin kullanımı

6.1 Koşullu Denetim - IF Deyimi

Bir PL/SQL programında karşılaştırma işlemi sonucunda bir eylemin yapılması söz konusu
ise, yani belirli deyimlerin çalıştırılması gerekiyorsa IF..THEN deyimine başvurulur. Bu
deyim şu şekilde tanımlanır:

IF koşul THEN
Deyimler;
END IF

Bu tanıma göre, ifade içinde belirtilen koşulun “doğru” olması halinde, IF..THEN ile END
IF arasında belirtilen deyimler çalışır. Eğer koşulun doğruluk değeri “yanlış” ise bu
aralıkta içinde tanımlanan deyim işlem görmez.

185
Örnek 1

PL/SQL bloğu içinde bir sayi isimli bir değişken tanımladıktan sonra bu değişkenin içine
90 değerini yerleştireceğiz. Daha sonra bu değişken değerini IF deyimi ile denetleyerek
100 den küçük olup olmadığını denetleyeceğiz. Bu koşul gerçekleşiyorsa bir mesaj değeri
elde edilecektir. Mesajı görüntülemek için mesaj isimli bir bağlı değişken, yani aşağıdaki
şekilde bir dış değişken tanımlanır.

SQL> VARIABLE mesaj VARCHAR2(30);

Bu amaçla yazılan PL/SQL bloğunu görmek için linke tıklayınız

DECLARE
sayi number(5) :=90;
BEGIN
IF sayi < 100
THEN
:mesaj :='kosul dogru ';
END IF;
END;
/

Program çalıştıktan sonra mesaj hemen görüntülenmez. mesaj isimli değişkenin içeriğini
görüntülemek için PRINT deyimini kullanıyoruz.

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

SQL> PRINT mesaj;

186
MESAJ
--------------------------------
KOŞUL DOĞRU

Örnek 2

personel tablosunu okuyarak, 5000' den fazla ücret alan olup olmadığını denetlemek
istiyoruz. Bunun için mesaj' ı yerleştirmek üzere bir dış değişken tanımlıyoruz.

SQL> VARIABLE mesaj VARCHAR2(40);

Bu amaçla yazılan PL/SQL bloğunu görmek için linke tıklayınız

DECLARE
buyuk_ucret NUMBER(9);
BEGIN
SELECT MAX(ucret) INTO buyuk_ucret FROM personel; IF buyuk_ucret >
5000
THEN
:mesaj :='5000 den fazla ücret alan var..';
END IF;
END;
/

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

Bu PL/SQL bloğu çalıştırıldıktan sonra PRINT komutu ile mesaj değişkeninin içeriğini
öğreniyoruz:

SQL> PRINT mesaj;

MESAJ
-------------------------------
5000 DEN FAZLA ÜCRET ALAN VAR..

6.1.1 Koşul Gerçekleşmiyorsa


Karşılaştırma işlemlerinde koşul gerçekleştiğinde, yani “doğru” değerini aldığında IF
içinde tanımlanan deyimlerin işlem gördüğünü öğrenmiş bulunuyoruz. Peki bu koşul
gerçekleşmediğinde nasıl bir yol izlenecektir? Bir koşulun gerçekleşmemesi durumunda
yerine getirilecek eylemleri belirlemek için ELSE sözcüğü kullanılır. Bu sözcük IF deyimi
içinde şu şekilde yer alacaktır:

IF koşul THEN
deyim 1;
ELSE
deyim 2;

187
END IF

Bu tanıma göre, ifade içinde belirtilen koşulun “doğru” olması halinde, IF içinde belirtilen
deyim 1 çalışır. Aksi durumda, yani koşulun doğruluk değeri “yanlış” ise deyim 2 deyimi
işlem görür.

Örnek

Bir SAYI değişkenine 200 değerini yerleştiriyoruz. Bu sayının 200 den küçük olup
olmadığını denetlemek istiyoruz. Koşulun gerçekleşmediği durumda farklı bir mesajı
görüntülemek için ELSE deyimi kullanılıyor. Mesajı görüntülemek için MESAJ isimli bir bağlı
değişken, yani bir dış değişken tanımlıyoruz.

SQL> VARIABLE mesaj VARCHAR2(30);

Bu amaçla düzenlenmiş olan PL/SQL bloğunu görmek için linke


tıklayınız

DECLARE
sayi number(5) :=200;
BEGIN
IF sayi < 100
THEN
:mesaj :='KOŞUL DOĞRU ';
ELSE
:mesaj :='KOŞUL YANLIŞ ';
END IF;
END;
/

Bu program çalıştırıldıktan sonra PRINT deyimi ile aşağıdaki sonuç elde edilir.

188
Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

SQL> PRINT mesaj;

MESAJ
--------------------------------
KOŞUL YANLIŞ

6.1.2 İç İçe IF Deyimleri

Koşul ifadelerinin tanımlanması amacıyla IF..THEN..ELSE..END IF deyimlerinin


kullanılabildiğini görmüş bulunuyoruz. Bazı PL/SQL bloklarında bir IF deyimi içinde bir
başka IF deyimi kullanılabilir.

IF koşul THEN
deyimler
ELSE
IF koşul THEN
deyimler
ELSE
deyimler
END IF;
END IF;

Bu tanım yerine, ELSE ve IF kelimeleri ELSIF biçiminde birleştirilerek yandaki ifade biçimi
de kullanılabilir. Bu durumda END IF deyimleri de ortak hale gelmiş olur.

IF koşul THEN
deyimler
ELSEIF koşul THEN
deyimler
ELSE
deyimler
END IF;

Örnek

Verilen üç adet sayısal değerin en küçüğünü bulan bir PL/SQL bloğu yazmak istiyoruz.

! Probleme uygun akış şemasını görmek için düğmeye tıklayınız.

189
Program içinden elde edilen sonucu aktarmak için bir SONUC isimli değişkeni SQL*Plus
ortamında şu şekilde tanımlıyoruz:

SQL> VARIABLE sonuc NUMBER;

Amacımıza uygun PL/SQL bloğunu görmek için linke tıklayınız

PL/SQL bloğu ise şu şekildedir:

190
-- Bu PL/SQL bloğu üç sayısal değer
-- arasından en küçük olanını seçer..
DECLARE
a NUMBER(5) :=7;
b NUMBER(5) :=5;
c NUMBER(5) :=11;
kucuk NUMBER;
BEGIN
IF a < b
THEN
IF b<c
THEN
kucuk :=a;
END IF;
ELSIF b>c
THEN
KUCUK :=c;
ELSE
KUCUK:=b;
END IF;
:sonuc :=kucuk;
END;
/

Bu blok çalıştırıldıktan sonra sonuc isimli değişkenin içeriği görüntülenir:

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

SQL> PRINT sonuc;

SONUC
----------
5

6.2 Döngü İşlemleri


PL/SQL bloklarının belirli bölümlerinin defalarca işlenmesi söz konusu olabilir. Bunu
sağlamak üzere döngülerden yararlanılır. PL/SQL bloklarında döngü işlemleri farklı
biçimlerde gerçekleşebilmektedir:

6.2.1 Sonsuz Döngüler

191
PL/SQL bloklarında kullanılabilecek döngüler içinde en basit yapılı olanlarıdır. Bu tür
döngülere basit döngüler'in yanı sıra sonsuz döngüler adı da verilmektedir. Söz
konusu döngü şu şekilde tanımlanmaktadır:

LOOP

deyimler;

END LOOP;

Görüldüğü gibi bu döngünün sonunu belirleyen herhangi bir deyim yoktur. Döngüden
çıkma olasılığı yoktur. O nedenle bu tür döngüye sonsuz döngü deniliyor.

6.2.1.1 Sonsuz Döngüden Koşulsuz Çıkış


Sonsuz döngüler doğal olarak sorun yaratcaktır. Peki bu durumda döngüden nasıl
çıkılacaktır? Sonsuz bir LOOP döngüsünden çıkmak için EXIT deyimi kullanılabilir. Bu
deyim, doğal olarak bir karşılaştırma işlemi sonucunda olacaktır. Bunun anlamı, EXIT
deyimi çoğunlukla bir IF deyimi içinde kullanılarak döngü sayısı denetlenir.

LOOP


IF koşul
THEN
EXIT;
END IF;

END LOOP;

192
Örnek

Bir PERSON isimli tabloya altı adet kayıt eklemek istiyoruz. Tablo iki sütundan
oluşmaktadır. Biz sadece birinci sütununa birden başlayan ve her defasında 1 artan bir
sayısal değer yerleştireceğiz. İkinci sütun ise boş kalacaktır. Amacımıza uygun PL/SQL
bloğunu LOOP döngüsü ile yaratıyoruz. Yeni eklenen personel numaraları ise 500 ile 506
arasında olacaktır.

Bu amaçla yazılmış PL/SQL bloğunu görmek için linke tıklayınız

DECLARE
sayi NUMBER := 500;

BEGIN
LOOP
-- Tabloya kayıt ekleme işlemi..
INSERT INTO person(per_no,per_adi)
VALUES (sayi, NULL);
sayi:= sayi + 1;
--Eğer 506 numaraya ulaşılmış ise
--Döngü terkedilecektir..
IF sayi >506
THEN
EXIT;
END IF;
END LOOP;
END;
/

Bu blok çalıştırıldığında, PERSON isimli tablo içine 7 adet yeni kayıt eklendiği ve personel
numarası olarak 500 ile 506 sayıları arasındaki değerlere yer verildiği görülecektir.
Tablonun içeriğini görüntülediğimizde, söylediklerimizin gerçekleştiği anlaşılır:

193
Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

SQL> SELECT * FROM PERSON;

PER_NO PER_ADI
---------- ---------
500
501
502
503
504
505
506

6.2.1.2 Sonsuz Döngüden Koşul Gerçekleştiğinde Çıkış


Bir döngüden belirli bir koşul gerçekleştiğinde IF deyimi ve EXIT deyimi yardımıyla nasıl
çıkabileceğimiz öğrenmiş durumdayız. Sonsuz döngülerden çıkmak üzere, bu yöntem
yerine çok daha kullanışlı bir başka yöntem bulunmaktadır. Bunun için EXIT WHEN
deyimleri kullanılır. Bu deyim aşağıda görüldüğü biçimde tanımlanıyor:

LOOP

EXIT WHEN koşul;

END LOOP;

Bu tanıma göre, LOOP döngüsü içinde EXIT WHEN ile belirlenen bir koşul gerçekleştiğinde
bu döngü terk edilecektir.

Örnek

194
Önceki örneği yeniden ele alalım. Bu örnek şu şekilde idi: Bir PERSON isimli tabloya altı
adet kayıt eklemek istiyoruz. Tablo iki sütundan oluşmaktadır. Biz sadece birinci
sütununa birden başlayan ve her defasında 1 artan bir sayısal değer yerleştireceğiz. İkinci
sütun ise boş kalacaktır. Amacımıza uygun PL/SQL bloğunu LOOP döngüsü ile yaratıyoruz.
Yeni eklenen personel numaraları ise 500 ile 506 arasında olacaktır. Bu kez WHEN EXIT
deyimlerini kullanarak sonsuz döngüden çıkacağız.

Bu amaca uygun olarak yazılmış PL/SQL bloğunu görmek için linke


tıklayınız

DECLARE
sayi NUMBER := 500;
BEGIN
LOOP
-- Tabloya kayıt ekleme işlemi..
INSERT INTO person(per_no,per_adi)
VALUES (sayi, NULL);
sayi:= sayi + 1;
--Eğer 506 numaraya ulaşılmış ise
--Döngü terkedilecektir..
EXIT WHEN sayi >506;
END LOOP;
END;
/

Bu PL/SQL bloğu çalıştırıldıktan sonra PERSON tablosuna belirlenen miktarda kayıt eklenir.

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

SQL> SELECT * FROM PERSON;

PER_NO PER_ADI
---------- ---------
500
501
502
503
504
505
506

6.2.2 Koşullu Döngüler-WHILE Döngüleri

Bir koşulun gerçekleşmesi durumunda belirli işlemlerin tekrarlanması söz konusu ise
WHILE döngülerinden yararlanılır. Bu döngü aşağıdaki şekil üzerinde görüldüğü biçimde
çalışmaktadır. Koşul sağlanmadığı sürece döngü içindeki hiçbir deyim çalışmayacaktır. Bu
denetim döngü bloğunun başında yapılır. Söz konusu WHILE döngüsü şu şekilde
tanımlanmaktadır:

WHILE koşul

195
LOOP

deyimler;

END LOOP;

Örnek 1

5 sayısal değerinden daha küçük olan tüm tamsayıları listelemek istiyoruz. Bu amaçla
aşağıda görüldüğü biçimde, WHILE deyimini kullanarak bir PL/SQL bloğu hazırlayabiliriz.
Listeyi elde etmek için DBMS_OUTPUT.PUT_LINE()paketini kullanıyoruz.

Amacımıza uygun PL/SQL bloğunu görmek için linke tıklayınız.

-- Bir sayisal degerden


-- daha kucuk olanlari listeler
DECLARE
n NUMBER := 5;
i NUMBER :=0;
BEGIN
WHILE i<n
LOOP
i:=i+1;
-- sonuclar listeleniyor...
DBMS_OUTPUT.PUT_LINE (i);
END LOOP;
END;
/

196
Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

Örnek 2

Daha önce ele alarak inceledğimiz bir örneği yeniden göz önüne alıyoruz: Bir PERSON
isimli tabloya altı adet kayıt eklemek istiyoruz. Tablo iki sütundan oluşmaktadır. Biz
sadece birinci sütununa birden başlayan ve her defasında 1 artan bir sayısal değer
yerleştireceğiz. İkinci sütun ise boş kalacaktır. Amacımıza uygun PL/SQL bloğunu bu kez
WHILE döngüsü ile yaratıyoruz. Yeni eklenen personel numaraları 500 ile 506 arasında
olacaktır.

Amacımıza uygun PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
sayi NUMBER := 500;
n NUMBER :=506;
BEGIN
WHILE sayi <= n
LOOP
-- Tabloya kayıt ekleme işlemi..
INSERT INTO person(per_no,per_adi)
VALUES (sayi, NULL);
sayi:= sayi + 1;
END LOOP;
END;
/

Bu blok çalıştırıldığında PERSON tablosu içine belirtilen kayıtlar eklenir.

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

SQL> SELECT * FROM PERSON;

PER_NO PER_ADI
---------- ---------------
500

197
501
502
503
504
505
506

6.2.3 Belirli Sayıda Tekrarlar-FOR Döngüleri

PL/SQL bloğu içinde bir ya da daha fazla sayıda deyimin belirli bir koşulun
gerçekleşmesine dek tekrarlanması söz konusu ise FOR deyimi kullanılır. Bu deyim şu
şekilde tanımlanmaktadır:

FOR sayaç IN alt_sınır..üst sınır

LOOP

deyimler;

END LOOP;

Bu deyimden şu anlaşılmaktadır: Döngü bir sayaca göre yapılacaktır. Yani her bir döngü
işlemi sayılacaktır. Döngü işlemi sayaç tamamlanıncaya dek devam edecektir. Sayaç
tamamlandığında döngü terk edilerek bir sonraki deyim işlem görmeye başlar.

Örnek 1

0 ile 5 arasındaki sayısal değerleri listelemek için bir PL/SQL bloğu hazırlayabiliriz.

Bu amaçla hazırlanmış PL/SQL bloğunu görmek için linke


tıklayınız.

198
DECLARE
BEGIN
-- Döngü tanımlanıyor..
FOR i IN 0..5
LOOP
-- sonuclar listeleniyor...
DBMS_OUTPUT.PUT_LINE (i);
END LOOP;
END;
/

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

Örnek 2

Klavye yardımıyla girilen iki tamsayı arasında kalan tüm tüm sayıların toplamını bulmak
istiyoruz. Başlangıc ve son sayılar bu toplama dahil edilmeyecektir.

Amacımıza uygun PL/SQL bloğunu görmek için linke tıklayınız.

-- Bu program girilen iki tamsayi arasinda kalan


-- tüm tamsayilarin toplamlarini hesaplar..
DECLARE
baslangic NUMBER :=1;
son NUMBER :=5;
toplam NUMBER :=0;
BEGIN
FOR i IN baslangic..son
LOOP
toplam:=toplam+i;
END LOOP;
-- sonuc listeleniyor...
DBMS_OUTPUT.PUT_LINE (toplam);
END;
/

Bu blok çalıştırıldığında 1,2,3,4,5 sayılarının toplamı olan 15 değeri görüntülenir.

199
6.2.4 Döngü Etiketleri
Bazı uygulamalarda içi içe döngüler yer alabilir. Örneğin bir LOOP döngüsü içinde bir
başka LOOP döngüsü yer alabilir. Bu tür döngülerde, döngülerden çıkış anında bir sorun
ile karşılaşılır.

Döngüden çıkış deyimi olarak kullanılan EXIT deyimi sadece en içteki döngüden çıkışı
sağlar. Ancak bazı durumlarda iç içe döngüden tümüyle çıkmak söz konusu olabilir. Böyle
durumlarda döngü etiketleri kullanılabilir. Bir döngüyü etiketlendirmek için şu şekilde bir
tanım yapılır:

<<etiket>>

Örneğin durum1 biçiminde etiketlenen bir LOOP döngüsü şu şekilde etiketlendirilebilir;

<<durum1>>

LOOP

deyimler;

END LOOP durum1;

Örnek

Aşağıdaki PL/SQL bloğu içinde, iç içe iki LOOP döngüsü bulunmaktadır. İkinci LOOP içinde
yer alan EXIT deyimi çalıştığında, her iki döngü de terk edilir.

<<son1>>
LOOP

200

LOOP

EXIT son1 WHEN ….
END LOOP;

END LOOP son1;

6.3 GOTO Deyimi İle Bir Etikete Sapılması

PL/SQL programları birer yapısal program olarak değerlendirilebilir. Böyle olunca,


programlar içinde GOTO deyiminin kullanılması tavsiye edilmez. Bu deyim, blok içinde
etiketlenen herhangi bir satıra sapılmasını sağlar. GOTO deyimi şu şekilde tanımlanır:

GOTO etiket;

Doğal olarak böyle bir işlemin gerçekleşebilmesi için belirtilen etiketin blok içinde
tanımlanmış olması gerekmektedir. Bu deyim dikkatli biçimde kullanılmalıdır. Örneğin, bir
IF deyiminde THEN bloğunda GOTO deyimi ile ELSE bloğun atlamak yanlış bir davranış
olacaktır.

Örnek

Blok içinde satir_gir isimli etikete sapılmasını sağlayan tanım aşağıda gösterildiği
biçimde yapılabilir:

BEGIN

GOTO satir_gir;

<<satir_gir>>

201
INSERT INTO personel VALUES …
END;

202
203
204
205
206
PL/SQL TABLOLARI VE KAYITLARI

Bu bölümde,

• PL/SQL Tabloları
• Kullanıcı Tanımlı PL/SQL Kayıtları

anlatılmaktadır.

Bölüm Hedefi
Bu bölümde aşağıda sıralanan konular ele alınarak
incelenecektir:

• PL/SQL Tablolarının (dizilerinin) Kullanımı


• Tablolar Nasıl Yaratılır?
• Tabloların Öznitelikleri
• Kullancı Tanımlı Kayıtlar
• Kayıtlar Nasıl Tanımlanır?

• Kayıtların Kullanılması

7.1 PL/SQL Tabloları


Bu bölümde özel bir tablo biçimiyle karşı karşıyayız. Bu tablolar, PL/SQL tabloları adını
taşıyan veri yapılarıdır. PL/SQL tabloları veri tabanı tablolarının bir benzeridir. Ancak her
yönüyle bir veri tabanı tablosuna benzemez. Farklıkları bulunmaktadır.

PL/SQL tabloları, PL/SQL bloklarında dizi (array) kullanma gereksinimini karşılar. Aslında
PL/SQL tabloları bir diziye benzer. Dizilerde olduğu gibi, aynı türdeki verileri içerir. Bu
tablonun her bir elemanı bir benzersiz (unique) indekse sahiptir.

PL/SQL tablolarının bildiğimiz dizilerden de bazı farklılıkları bulunmaktadır. Dizilerin


boyutları sabit olmasına karşılık, PL/SQL tablolarının boyutları dinamiktir ve istenildiği
kadar büyüyebilir. Bir diğer fark, dizilerde elemanların konumlarını belirten ve sıfırdan
başlayan ardışık indeks sayıları kullanılmaktadır. PL/SQL tabloları ise bu tür indeksleri
kullanmaz. Onun yerine, örneğin 101, 455, 678 vb gibi herhangi BINARY_INTEGER
değerleri, yani personel numaralarını indeks olarak kullanabilir.

207
7.1.1 PL/SQL Tablolarının Yaratılması
PL/SQL tablolarının kullanılabilmesi için, PL/SQL blokları içinde DECLARE bölümünde
tanımlanması gerekmektedir. Bir PL/SQL tablosu yanda belirtildiği biçimde yaratılır.

Tablo için veri türü şu şekilde tanımlanır:

TYPE tablo veri türü IS TABLE OF veri türü

INDEX BY BINARY_INTEGER;

Tablonun indeksi BINARY_INTEGER veri türüne sahip olmalıdır. Bu veri türü -2147483647
ile +2147483647 arasındaki tamsayıları simgeler.

Tablonun veri türü tanımlandıktan sonra. Bu tablonun PL/SQL blokları içinde


kullanılabilmesi için bir değişkene atanması söz konusu olacaktır. Bu atama şu şekilde
gerçekleştirilebilir:

208
tablo adı tablo veri türü;

Örnek 1

Bir PL/SQL tablosu yaratmak istiyoruz. Bu tablo tarih veri türüne sahip veriler içerecektir.

! Amacımıza uygun tablo tanımını görmek için tablo tanımı düğmesine tıklayınız.

DECLARE
TYPE tarih IS TABLE OF DATE
INDEX BY BINARY_INTEGER;
tarih_dizi tarih;

Burada TYPE deyimi ile bir PL/SQL tablosu için veri türü tanımı yapılmaktadır. Tanımın
hemen ardından, bu tanım bir değişkene atanarak, bloklar içinde kullanılabilmesi için
hazır hale getirilmektedir.

DECLARE
TYPE ucret_turu IS TABLE OF personel.ucret%TYPE
INDEX BY BINARY_INTEGER;
ucret_tablo ucret_turu;

7.1.2 PL/SQL Tablolarının Kullanılması


Bir PL/SQL tablosu tanımlandıktan sonra doğal olarak bloklar içinde kullanılması söz
konusu olacaktır. Bir PL/SQL tablosuna gereksinim duyulduğunda başvurmak
gerekecektir. Bunun için, söz konusu tablonun elemanlarına indeks yoluyla erişilir.

tablo_adı (indeks)

Örneğin test_tablo isimli bir PL/SQL tablosunun üçüncü elemanına ulaşmak için,

test_tablo(3)…

biçiminde bir tanım yapılabilir.

Örnek 1

Bir PL/SQL tablosu içine üç değeri yerleştirdikten sonra bu değerleri tek tek görüntülemek
istiyoruz.

209
Amacımıza uygun PL/SQL bloğunu görmek için linke tıklayınız.

-- PL/SL tablosuna üç değeri yerleştirdikten


-- sonra bu değerler görüntülenecektir…
DECLARE
-- tablo tanımlanıyor..
TYPE test_turu IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
test_tab test_turu;
BEGIN
-- tabloya değerler yerleştiriliyor..
test_tab(1) :=101;
test_tab(2) :=119;
test_tab(3) :=125;
FOR i IN 1..3
LOOP
-- sonuc listeleniyor...
DBMS_OUTPUT.PUT_LINE (test_tab(i));
END LOOP;
END;

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

101

119

125

Örnek 2

Veri tabanında yer alan personel tablosunda en yüksek ücretin ne olduğunu belirleyerek,
bu değeri bir tablo içine yerleştirmek istiyoruz.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- tablo tanımlanıyor..
TYPE ucret_turu IS TABLE OF personel.ucret%TYPE
INDEX BY BINARY_INTEGER;
ucret_tab ucret_turu;
BEGIN
-- personel tablosundan okunan değer
-- PL/SQL tablosuna yerleştiriliyor..

210
SELECT MAX(ucret)
INTO ucret_tab(1)
FROM PERSONEL;
DBMS_OUTPUT.PUT_LINE (ucret_tab(1));
END;

Bu blok çalıştırıldığında, personel ücetleri arasında en fazla olanı SELECT deyimi ile
bulunur ve bu değer ucret_tab tablosunun birinci elemanı olarak atanır.

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

8750

Örnek 3

Bu kez aynı tablodan en fazla ve en az ücretleri elde ederek PL/SQL tablosu içine
yerleştirmek ve sonuçları listelemek istiyoruz.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- tablo tanımlanıyor..
TYPE ucret_turu IS TABLE OF personel.ucret%TYPE
INDEX BY BINARY_INTEGER;
ucret_tab ucret_turu;
BEGIN
-- personel tablosundan okunan değerler
-- PL/SQL tablosuna yerleştiriliyor..
SELECT MAX(ucret), MIN(ucret)
INTO ucret_tab(1) , ucret_tab(2)
FROM PERSONEL;
DBMS_OUTPUT.PUT_LINE (ucret_tab(1));
DBMS_OUTPUT.PUT_LINE (ucret_tab(2));
END;

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

8750

2000

7.1.3 Tablo Öznitelikleri

211
PL/SQL tabloları yaratıldıktan sonra üzerinde birçok işlem yapılabilir. Bunun için tabloya
ilişkin belirli öznitelikler (attribute) kullanılabilmektedir. Aşağıda bu öznitelikleri
özetliyoruz. PL/SQL tablo öznitelikleri şu şekilde tanımlanır:

tablo adı. öznitelik

212
213
7.1.3.1 Tablonun Eleman Sayısı
Bazı uygulamalarda PL/SQL tablosunun kaç elemandan oluştuğunu bulmak gerekebilir.
Böyle durumlarda PL/SQL tablolarının COUNT özniteliği kullanılır. Bu öznitelik şu şekilde
tanımlanıyor:

tablo adı.COUNT

Örnek

personel tablosunda en az ve en fazla ücretleri elde ettikten sonra bir PL/SQL tablosuna
yerleştiriyoruz ve daha sonra bu tablonun elemanlarını ekran üzerinde listeliyoruz.
Listelemeyi FOR döngüsü ile yapıyoruz. Döngü sınırı PL/SQL tablosunun eleman sayısı
kadar olmalıdır. Bunu sağlamak için COUNT kullanılıyor.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- tablo tanımlanıyor..
TYPE ucret_turu IS TABLE OF personel.ucret%TYPE
INDEX BY BINARY_INTEGER;
ucret_tab ucret_turu;
BEGIN
-- personel tablosundan okunan değerler
-- PL/SQL tablosuna yerleştiriliyor..
SELECT MAX(ucret), MIN(ucret)
INTO ucret_tab(1) , ucret_tab(2)
FROM PERSONEL;
FOR i IN 1..ucret_tab.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE (ucret_tab(i));
END LOOP;
END;

214
Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

8750

2000

7.1.3.2 Tablonun İlk ve Son Elemanları


Bir PL/SQL tablosunun ilk ve son elemanının indeksini elde etmek gerekebilir. Bu amaçla
söz konusu PL/SQL tablolarının FIRST ve LAST öznitelikleri kullanılır. Bu nitelikler şu
şekilde tanımlanıyor:

tablo adı.FIRST

tablo adı.LAST

Örnek

Bir dizi içine beş adet sayısal değer yerleştirdikten sonra, tablonun birinci ve sonuncu
elemanının indekslerini elde etmek istiyoruz.

Bu amaca yönelik olarak düzenlenen PL/SQL bloğunu görmek için linke


tıklayınız.

DECLARE
-- tablo tanımlanıyor..
TYPE test_turu IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
test_tab test_turu;
BEGIN

215
-- tabloya değerler yerleştiriliyor..
test_tab(1) :=101;
test_tab(2) :=119;
test_tab(3) :=125;
test_tab(4) :=35;
test_tab(5) :=196;
DBMS_OUTPUT.PUT_LINE ('İlk=' ||test_tab.FIRST);
DBMS_OUTPUT.PUT_LINE ('Son=' ||test_tab.LAST);
END;

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

İlk=1

Son=5

7.1.3.3 Tablo Elemanlarının Silinmesi


Bir PL/SQL tablosunun belirli bir satırı ya da birden fazla satırı silinebilir. Bu amaçla
DELETE özniteliğinden yararlanılır. Bu öznitelik farklı biçimlerde kullanılabilir.

DELETE

DELETE(n)

DELETE(m,n)

Birinci tanım tablonun tüm elemanlarının silinmesini sağlar. İkinci tanım belirli bir n
satırının silinmesini sağlar. Burada sözü edilen n ilgili tablonun indeks numarasıdır. Son
tanım ise n ve m gibi belirli iki satır arasındaki tüm satırların silinmesini sağlar.

216
Örnek 1

Bir PL/SQL tablosuna 5 adet değer yerleştirdikten sonra bunlar arasında 4. ve 5.


elemanları tablodan silmek istiyoruz.

! Bu amaç ile yazılan programı görmek için program düğmesine tıklayınız.

DECLARE
-- tablo tanımlanıyor..
TYPE test_turu IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
test_tab test_turu;
BEGIN
-- tabloya değerler yerleştiriliyor..
test_tab(1) :=101;
test_tab(2) :=119;
test_tab(3) :=125;
test_tab(4) :=35;
test_tab(5) :=196;
-- tablonun 4. ve 5. elemanları siliniyor..
test_tab.DELETE(4,5);
-- tablonun son hali görüntüleniyor..
FOR i IN test_tab.FIRST .. test_tab.LAST
LOOP
DBMS_OUTPUT.PUT_LINE (test_tab(i));
END LOOP;
END;

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

101

119

125

Örnek 2

Önceki örneği yeniden ele alalım. Bu kez sadece 4. elemanını silmek istediğimizi
varsayalım.

Bu durumda programı aşağıda gösterildiği biçimde hazırlıyoruz.

! Bu amaç ile yazılan programı görmek için program düğmesine tıklayınız.

217
DECLARE
-- tablo tanımlanıyor..
TYPE test_turu IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
test_tab test_turu;
BEGIN
-- tabloya değerler yerleştiriliyor..
test_tab(1) :=101;
test_tab(2) :=119;
test_tab(3) :=125;
test_tab(4) :=35;
test_tab(5) :=196;
-- tablonun 4. elemanı siliniyor..
test_tab.DELETE(4);
-- tablonun son hali görüntüleniyor..
FOR i IN test_tab.FIRST .. test_tab.LAST
LOOP
DBMS_OUTPUT.PUT_LINE (test_tab(i));
END LOOP;
END;

Bu program çalıştırıldığında, sadece üç elemanı görüntüleyecek ve ardından bir hata


mesajı ile bloğun çalışması sona erecektir. Hatanın nedeni nedir ? Hata silme işlemi
ardından, tablo elemanlarının görüntülenmesi esnasında ortaya çıkmaktadır, çünkü
tablonun 4. elemanı silinmiştir. Bu elemanın indeksi 4‘dür. FOR döngüsü içinde bu indeks
kullanılmaya çalışılıyor. Söz konusu indeks silindiği için okunamayacaktır ve bloğun
çalışması bir hata mesajı ile kesilecektir.

7.2 Kullanıcı Tanımlı PL/SQL Kayıtları


PL/SQL bloklarında kullanılan bir diğer veri yapısı “kayıt” olarak isimlendirilmektedir. Bir
kayıt birbirleriyle ilişkili alanların bir arada tanımlanması ile oluşturulur. Kayıtın bir adı
vardır. Ayrıca tıpkı PL/SQL tablolarında olduğu gibi, bir indeks yardımıyla kayıtlara ulaşılır.
Kayıtın her bir alanı farklı veri türüne sahip olabilir.

7.2.1 Kayıt Türünün Tanımlanması


PL/SQL kayıt türünün oluşturulması amacıyla, blokların DECLARE bloğu için bir tanım
yapılması gerekmektedir. Kayıt türlerinin yaratılabilmesi için öncelikle aşağıda görüldüğü
biçimde bir tür tanımı yapılmalıdır.

TYPE kayıt türü adı IS RECORD (alan tanımları);

218
Örnek

Aşağıda bir PL/SQL kayıt türü tanımlanmaktadır. Bu kayıt, p_no, p_adi ve p_ucret gibi
üç alandan oluşmaktadır. Bu kayıt türünün adı per_kayit_turu olarak belirlenmiştir.

DECLARE
TYPE per_kayit_turu IS RECORD (
p_no NUMBER(3),
p_adi VARCHAR2(15),
p_ucret NUMBER);

Bu tanım içindeki alan türleri, bir diğer değişkenden ya da bir veri tabanı tablosunun
alanlarından alınabilir. Böyle bir amaç için %TYPE anahtar kelimesini kullanıyoruz.
Aşağıdaki örnek, kaydın alanlarına ait veri türlerinin personel tablosundan kopyalandığını
göstermektedir:

DECLARE
TYPE per_kayit_turu IS RECORD (
p_no personel.personel_no%TYPE,
p_adi personel.adi%TYPE,
p_ucret personel.ucret_no%TYPE,);

7.2.2 Kaydın Tanımlanması


RECORD anahtar kelimesi kullanılarak alan türü tanımlandıktan sonra bu türe dayanarak
bir kaydın yaratılması gerekmektedir. Bunun için, yine DECLARE bloğu içinde aşağıda
görüldüğü biçimde bir kayıt tanımlanır:

kayıt_adı kayıt_türü_adı;

Örnek

Aşağıdaki blok içinde önce bir kayıt türü tanımlıyoruz ve ardından bu türe dayanarak
per_kayit isimli bir kayıt yaratıyoruz.

219
DECLARE
TYPE per_kayit_turu IS RECORD (
p_no NUMBER(3),
p_adi VARCHAR2(15),
p_ucret NUMBER);
per_kayit per_kayit_turu;

7.2.3 Kayıtların Kullanılması


Kayıtlar bu şekilde tanımlandıktan sonra, bu kayıtların içerdiği alanlara erişim söz
konusudur. Kaydın her bir alanına, o alanın ismi kullanılarak erişilir. Bunun için şu şekilde
bir tanım kullanılır:

kayıt_adı.alan_adı

Alan isimleri bu şekilde kullanılarak, bu alanlara değer atanabilir veya gerektiğinde


PL/SQL bloğunun içinde kullanılabilir. Kayıt alanlarına blok içinde doğrudan değerler
atanabileceği gibi, gerektiğinde veri tabanı tablolarından da veri okunarak aktarılabilir.

Örnek 1

Bir kayıt tanımlandıktan sonra bu kaydın alanlarına değerler kaydetmek ve ardından bu


kaydın her bir alanının içeriğini görüntülemek istiyoruz.

Amacımıza uygun PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- Kayıt türü tanımlanıyor..
TYPE per_kayit_turu IS RECORD
(per_no NUMBER(3),
p_adi VARCHAR2(15),
p_ucret NUMBER);
-- Kayıt tanımlanıyor..
per_kayit per_kayit_turu;
BEGIN
-- alanlara bilgi yerleştiriliyor..
per_kayit.per_no := 305
per_kayit.p_adi := 'BEGUM';

220
per_kayit.p_ucret :=6650;

-- alanlardaki bilgiler görüntüleniyor..


DBMS_OUTPUT.PUT_LINE (per_kayit.per_no);
DBMS_OUTPUT.PUT_LINE (per_kayit.p_adi);
DBMS_OUTPUT.PUT_LINE (per_kayit.p_ucret);

END;

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

305

BEGUM

6650

Örnek 2

personel tablosundan bazı verileri SELECT deyimi ile okuyarak kayıt alanlarına
yerleştirmek istiyoruz.

Bu amaca yönelik olarak düzenlenen PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- Kayıt türü tanımlanıyor..
TYPE per_kayit_turu IS RECORD (
per_no NUMBER(3),
p_adi VARCHAR2(15),
p_ucret NUMBER);

-- Kayıt tanımlanıyor..
per_kayit per_kayit_turu;
BEGIN
-- tablodan okunan veriler kayıt
-- alanlarına yerleştiriliyor..
SELECT personel_no, adi, ucret
INTO per_kayit.per_no, per_kayit.p_adi, per_kayit.p_ucret
FROM personel
WHERE personel_no=101;
-- alanlardaki bilgiler görüntüleniyor..
DBMS_OUTPUT.PUT_LINE (per_kayit.per_no);
DBMS_OUTPUT.PUT_LINE (per_kayit.p_adi);
DBMS_OUTPUT.PUT_LINE (per_kayit.p_ucret);
END;

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

221
101

BURAK

7000

7.2.4 %ROWTYPE Özniteliği

Veri tabanındaki bir tablodan SELECT ya da FETCH deyimleri ile bilgi alınırken, kayıt
alanlarını tek tek tanımlamaya gerek olmayacaktır. FETCH deyimi imleçlerden bilgi
okumayla ilgili bir deyimdir. Bu deyimi daha sonraki konularımızda ele alarak
inceleyeceğiz. Böyle bir amaç şu şekilde bir tanım yapılmalıdır:

Bu tanımda görüldüğü gibi, bir veri tabanı tablosu kullanılacak ise, kaydın her bir alanı
için TYPE ile veri türü tanımını yapmaya gerek yoktur. Sadece yukarıda görüldüğü
biçimde kayıt adı tanımlanır.

Örnek

Veri tabanındaki personel isimli tablodan 110 numaralı personele ait bilgileri alarak bir
PL/SQL kayıtı üzerine yerleştireceğiz ve daha sonra bu bilgiler arasında iki alanın içeriğini
görüntüleyeceğiz.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- Kayıt türü tanımlanıyor..
per_kayit personel%ROWTYPE;
BEGIN
-- tablodan okunan veriler kayıt alanlarına yerleştiriliyor..
SELECT *
INTO per_kayit
FROM personel
WHERE personel_no=110;
-- alanlardaki bilgiler görüntüleniyor..
DBMS_OUTPUT.PUT_LINE (per_kayit.personel_no);
DBMS_OUTPUT.PUT_LINE (per_kayit.adi);
END;

Bu program çalıştığında ilgili personele ilişkin personel numarası ve adı görüntülenir:

222
Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

110

DILAY

223
224
225
226
227
228
İMLEÇLER

Bu bölümde;

• İmleç
• Belirtilmiş İmleçler
• İmleçlerin Çalışma Biçimi
• İmleçlerin Tanıtılması
• İmleçlerin Açılması ve Kapatılması
• İmleçten Bilgi Alma
• İmleç Öznitelikleri
• İmleçlere Dayalı Kayıtlar
• FOR Döngüsü ile İmleçlerin Tanımlanması
• Parametrelerin Kullanımı

anlatılmaktadır.

Bölüm Hedefi
Bu bölümde aşağıda sıralanan konular ele alınarak
incelenecektir:

• İmleç Nedir?
• Belirtilmiş İmleçler
• İmleçlerin Çalışma Biçimi
• İmleçlerin Tanıtılması
• İmleçlerin Açılması ve Kapatılması
• İmleçten Bilgi Alma
• İmleç Öznitelikleri
• İmleçlere Dayalı Kayıtlar
• FOR Döngüsü ile İmleçlerin Tanıtılması

• Parametrelerin Kullanımı

8.1 İmleç Nedir ?


PL/SQL de SQL deyimlerinin çalıştırılması sonucunda elde edilen değerler üzerinde işlem
yapmak üzere imleç (cursor) adı verilen yapılardan yararlanılır. İmleçler bellekte bir
kayıt kümesinin oluşturulmasına neden olur. Bu küme üzerindeki her bir kayıda erişerek
üzerinde işlemler yapılabilir.

PL/SQL de yanda belirtildiği gibi iki tür imleçten söz edilir.

229
Örtülü imleçler, önceki bölümde ele alarak incelediğimiz biçimde yaratılır. Bu tür imleçleri
yaratmak için özel bir işlem yapılmaz. SELECT veya DML deyimlerinin kullanıldığı bir
PL/SQL bloğunda örtülü imleçler otomatik olarak açılır. Bu tür imleçleri sorgulama
işlemlerinde kullanırken, sadece bir kayıt döndüren SELECT deyimleri için geçerli
olabileceği unutulmamalıdır.

8.1 İmleç Nedir ?


PL/SQL de SQL deyimlerinin çalıştırılması sonucunda elde edilen değerler üzerinde işlem
yapmak üzere imleç (cursor) adı verilen yapılardan yararlanılır. İmleçler bellekte bir
kayıt kümesinin oluşturulmasına neden olur. Bu küme üzerindeki her bir kayıda erişerek
üzerinde işlemler yapılabilir.

PL/SQL de yanda belirtildiği gibi iki tür imleçten söz edilir.

Örtülü imleçler, önceki bölümde ele alarak


incelediğimiz biçimde yaratılır. Bu tür imleçleri
yaratmak için özel bir işlem yapılmaz. SELECT veya
DML deyimlerinin kullanıldığı bir PL/SQL bloğunda
örtülü imleçler otomatik olarak açılır. Bu tür imleçleri
sorgulama işlemlerinde kullanırken, sadece bir kayıt
döndüren SELECT deyimleri için geçerli olabileceği
unutulmamalıdır.

Belirtilmiş imleçler ise, bu bölümün konusunu


oluşturmaktadır. Aksi belirtilmedikçe, imleç kelimesi ile
belirtilmiş imleçler kastedilecektir. Bu imleçlerin en
büyük özelliği, birden fazla kayıt içermesidir. Bir
sorgulama işleminde SELECT deyimi kullanıldığında,
seçilen kayıtların tümü bellekte imleç içine yerleştirilir.
Bu tür imleçleri tanımlamak ve kullanmak için özel
PL/SQL deyimleri vardır. Aşağıdaki bölümlerde bu
işlemleri ele alarak inceleyeceğiz.

230
8.2 Belirtilmiş İmleçler
Bir imleçi oluşturmak için herşeyden önce bir sorgulama işlemine ihtiyaç duyulur. SELECT
deyimi ile yapılan sorgu sonucunda elde edilen veriler imleç üzerine yerleşir.

8.3 İmleçlerin Çalışma Biçimi


İmleçleri PL/SQL blokları içinde kullanabilmek için belirli işlemlerin yerine getirilmesi
gerekiyor. Bu işlemleri şu şekilde sıralamamız mümkündür:

a. İmleçin tanıtılması. Bu işlem DECLARE bölümünde yapılır.


b. Belirtilen imlecin açılması. Bu amaçla OPEN deyimi kullanılır.
c. İmleçten kayıdın getirilerek değişkenlere aktarılması. Bu işlem FETCH deyimi ile
yapılır.
d. İmlecin kapatılması. Bu işlem CLOSE deyimi ile yapılır.

231
8.4 İmleçlerin Tanıtılması
Bir imleci PL/SQL bloğu içinde kullanabilmek için öncelikle DECLARE bloğu içinde
tanımlanmış olması gerekmektedir. Bunun için CURSOR deyimine başvurulur. Söz konusu
deyim şu şekilde tanımlanır:

CURSOR imleç_adı

SELECT deyimi;

232
Örnek

Veri tabanında yer alan personel tablosundan personel numaralarını ve isimlerini


okuyarak bir imleç üzerine yerleştirmek istiyoruz. Bu imlecin adı per_imlec olacaktır.
Amacımıza uygun olarak aşağıdaki tanım yapılır:

DECLARE
CURSOR per_imlec IS
SELECT personel_no, adi
FROM personel;

8.5 İmleçlerin Açılması ve Kapatılması


İmleçler DECLARE bölümünde PL/SQL bloğuna tanıtıldıktan sonra, kullanılabilmesi için
açılması gerekecektir. Bu amaçla OPEN deyimine başvurulur. Bu deyim şu şekilde
tanımlanır:

OPEN imleç adı;

Bu deyim, belirlenen sorgunun çalışmasını ve sonuçlarının kayıt kümesi üzerine


yerleşmesini sağlar. Kayıt göstergesi (pointer) bu aşamada birinci kaydı göstermektedir.
Kayıt göstergesi şu anda hangi kayıt üzerinde işlem yaptığımızı gösterir. Açık olan bir
imleci kapatmak gerekecektir. Böyle bir işlem için,

CLOSE imleç adı;

deyimi kullanılır. Bir imleç kapatıldıktan sonra gerekiyorsa, OPEN deyimi ile yeniden
açılabilir.

233
Örnek

per_imlec isimli bir imleci tanımladıktan sonra açmak istiyoruz. Bunun için aşağıda
belirtildiği biçimde bir yol izlenir:

DECLARE
-- imlecin tanıtılması....
CURSOR per_imlec IS
SELECT personel_no, adi
FROM personel;
BEGIN
-- imlecin açılması...
OPEN per_imlec;

-- imlecin kapatılması...
CLOSE per_imlec;
END;

8.6 İmleçten Bilgi Alma


Bir imleç açıldıktan sonra, sıra bu imleçten bilgi okumaya gelmiştir. Açık olan bir imleçten
veri getirmek için FETCH deyimi kullanılır. Bu deyim aşağıda gösterildiği biçimde
tanımlanır:

FETCH imleç_adı INTO değişkenler;

Bu deyim, imleç değişkenlerinin içerdiği değerleri INTO sonunda belirtilen PL/SQL


değişkenlere aktaracaktır.

234
Örnek

personel tablosundan personelin numarasını ve adını okuyarak bir imleç içine yerleştiren
ve sonunda imleç içindeki bu değerleri listeleyen bir PL/SQL bloğu yazalım.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız

DECLARE
v_no personel.personel_no%TYPE;
v_adi personel.adi%TYPE;
-- imlecin tanıtılması....
CURSOR per_imlec IS
SELECT personel_no, adi
FROM personel;
BEGIN
-- imlecin açılması...
OPEN per_imlec;
-- imleç değerlerinin okunarak
-- değişkenlere atanması..
FOR i IN 1..5
LOOP
FETCH per_imlec INTO v_no, v_adi;
-- sonuçların görüntülenmesi…
DBMS_OUTPUT.PUT_LINE (v_no|| ' '||v_adi);
END LOOP;

-- imlecin kapatılması..
CLOSE per_imlec;
END;

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

101 BURAK

235
105 BEGUM

120 SELIN

110 DILAY

130 SEZIN

8.7 İmleç Öznitelikleri


İmleçlerle birlikte kullanılabilecek bazı öznitelikler bulunmaktadır. Bu nitelikler her zaman
kullanılmaz. Sadece gerek duyulduğunda başvurulur. İmleç öznitelikleri aşağıda
belirtildiği biçimde tanımlanmaktadır:

imleç adı%öznitelik

Aşağıdaki tabloda imleç ile birlikte kullanılabilecek özniteliklere yer verilmektedir.

Öznitelik Veri türü Anlamı

%ISOPEN BOOLEAN İmleç açık ise TRUE döndürür.

%NOTFOUND BOOLEAN En son FETCH işlemi bir satır döndürmemiş ise TRUE döndürür.

%FOUND BOOLEAN En son FETCH işlemi bir satır döndürmüş ise TRUE döndürür.

%ROWCOUNT NUMBER Şimdiye dek döndürülen satırların sayısını verir.

Örnek 1

PL/SQL bloğunda bir imlecin açık olup olmadığı denetleyen, eğer açık değil ise açılması
işlemi yerine getiren PL/SQL bloğu yazalım.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
v_no personel.personel_no%TYPE;
v_adi personel.adi%TYPE;
-- imlecin tanıtılması....
CURSOR per_imlec IS
SELECT personel_no, adi
FROM personel;
BEGIN
-- imlecin açılması...
IF NOT per_imlec%ISOPEN
THEN
OPEN per_imlec;
END IF;
-- imleç değerlerinin okunarak
-- değişkenlere atanması..

236
FOR i IN 1..5
LOOP
FETCH per_imlec INTO v_no, v_adi;
-- sonuçların görüntülenmesi…
DBMS_OUTPUT.PUT_LINE (v_no|| ' '||v_adi);
END LOOP;
-- imlecin kapatılması..
CLOSE per_imlec;
END;

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

101 BURAK

105 BEGUM

120 SELIN

110 DILAY

130 SEZIN

Örnek 2

Önceki örnekte imleçten veri getirme işlemini FOR döngüsü içinde yapmıştık. Aynı bloğu
bu kez sonsuz LOOP döngüsü içinde düzenleyelim.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
v_no personel.personel_no%TYPE;
v_adi personel.adi%TYPE;
-- imlecin tanıtılması....
CURSOR per_imlec IS
SELECT personel_no, adi
FROM personel;
BEGIN
-- imlecin açılması...
IF NOT per_imlec%ISOPEN
THEN
OPEN per_imlec;
END IF;
-- imleç değerlerinin okunarak
-- değişkenlere atanması..
LOOP

237
FETCH per_imlec INTO v_no, v_adi;
EXIT WHEN per_imlec%ROWCOUNT > 7 OR
per_imlec%NOTFOUND;
-- sonuçların görüntülenmesi…
DBMS_OUTPUT.PUT_LINE (v_no|| ' '||v_adi);
END LOOP;
-- imlecin kapatılması..
CLOSE per_imlec;
END;

Bu program çalıştırıldığında %ROWCOUNT niteliği ile döngünün sayısı denetlenmektedir.


Doğal olarak 8. eleman okunduğunda, bu kayıt işlem görmeden döngü dışına çıkılacak ve
7 satırı yazdırılacaktır.

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

101 BURAK

105 BEGUM

120 SELIN

110 DILAY

130 SEZIN

160 AHMET

200 ALI

8.8 İmleçlere Dayalı Kayıtlar


Önceki bölümde PL/SQL kayıtlarını görmüştük. Bu kez aynı kayıtları bir imlece göre
yaratmak istiyoruz. Bunun için, belirlenen bir kaydın bir imlece bağlı olarak tanımlanması
yeterlidir. Kayıt tanımlandıktan sonra FETCH işlemi ile söz konusu kayıt içine ilgili veriler
yerleştirilir.

Örnek

Veri tabanında yer alan personel isimli tablodan personel numarası ve isimlerini
okuyarak gecici isimli bir başka tabloya bu satırları eklemek istiyoruz.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- imlecin tanıtılması....
CURSOR per_imlec IS
SELECT personel_no, adi

238
FROM personel;
-- imlece dayalı kayıtın tanımlanması..
per_kayit per_imlec%ROWTYPE;
BEGIN
OPEN per_imlec;
-- imleç değerlerinin okunarak kayıt içine
-- yerleştirilmesi ve diğer tabloya satır ekleme..
LOOP
FETCH per_imlec INTO per_kayit;
EXIT WHEN per_imlec%NOTFOUND;
INSERT INTO gecici (p_no, p_adi)
VALUES(per_kayit.personel_no,per_kayit.adi);
END LOOP;

-- Sonuçların kalıcı hale getirilmesi...


COMMIT;
-- imlecin kapatılması..
CLOSE per_imlec;
END;

Yukarıdaki PL/SQL bloğunun DECLARE bölümünde,

per_kayit per_imlec%ROWTYPE;

ifadesi ile, per_kayit isimli bir kayıt tanımlandığı ve bu kayıt alanlarının imleç alanları ile
aynı isimde ve veri türünde olduğu anlaşılmaktadır. INSERT INTO işleminde ise bu
kayıtın alanları kullanılmaktadır. Bu blok çalıştırıldıktan sonra belirlenen kayıtlar gecici
isimli tablo içine eklenir. Bu tablonun içeriği görüntülenirse, amacımıza ulaştığımız
anlaşılır.

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

SQL> SELECT * FROM gecici;

P_NO P_ADI
---------- ----------
101 BURAK
105 BEGUM
120 SELIN
110 DILAY
130 SEZIN
160 AHMET
200 ALI
150 AYBIKE
155 AYSE
250 ERSIN
300 HALIT
140 DILARA
350 ORCUN

8.9 FOR Döngüsü İle İmleçlerin Tanımlanması

239
İmleçleri tanımlamak ve kullanmak için nasıl bir yol izleneceğini görmüş bulunuyoruz.
Ancak imleçleri tanımlamak için çok kısa bir yol daha bulunmaktadır. Bu tanımlama FOR
döngüsü yardımıyla yerine getirilir. FOR deyimi bu amaçla şu şekilde tanımlanır:

FOR deyimi bu şekilde tanımlandığında, OPEN ile imleci açma, FETCH ile veri okuma ve
CLOSE ile imleci kapama işlemlerini tanımlamaya gerek yoktur. Bu işlemler ve kayıt
tanımlama işlemleri örtülü olarak (imlicit), yani FOR tarafından otomatik olarak
gerçekleştirilir.

FOR deyimi içinde SELECT sorgusunu tanımlayarak, imleç işlemlerini daha da


basitleştirebiliriz. Şöyle ki, FOR deyiminin IN anahtar kelimesi içinde sorguyu
yerleştirebiliriz.

FOR kayıt adı IN (SELECT sorgusu)

LOOP

deyimler…

END LOOP;

Bu durumda DECLARE bloğunda imleci ve sorgu ifadesini tanımlamaya gerek yoktur. Hatta
imleçlerle ilgili şu ana kadar gördüğümüz deyimlerin hiçbirini kullanmaya gerek yoktur.
PL/SQL imleç işlemlerini örtülü olarak gerçekleştirir.

Örnek 1

personel isimli veri tabanı tablosundan personel numarası ile adını okuyarak, bu verileri
per_imlec imlecine yerleştirmek istiyoruz. Daha sonra bu imleç içindeki tüm satırları tek
tek görüntüleyeceğiz.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
CURSOR per_imlec IS
SELECT personel_no, adi
FROM personel;

240
BEGIN
FOR per_kayit IN per_imlec LOOP
DBMS_OUTPUT.PUT_LINE (per_kayit.personel_no
|| ' ' ||per_kayit.adi);
END LOOP;
END;

PL/SQL bloğunda,

FOR per_kayit IN per_imlec LOOP

ifadesi ile per_imlec imlecindeki veriler per_kayit isimli PL/SQL kaydına


kopyalanmaktadır. Bu kayıtttan ilgili alanlar okunarak listelenmektedir.

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

101 BURAK

105 BEGUM

120 SELIN

110 DILAY

130 SEZIN

160 AHMET

200 ALI

150 AYBIKE

155 AYSE

250 ERSIN

300 HALIT

140 DILARA

350 ORCUN

Örnek 2

Önceki örneği, FOR deyimi içinde sorgu işlemini yerleştirerek yeniden düzenleyelim.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

241
BEGIN
FOR per_kayit IN (SELECT personel_no, adi
FROM personel)
LOOP
DBMS_OUTPUT.PUT_LINE (per_kayit.personel_no
|| ' ' ||per_kayit.adi);
END LOOP;
END;

Yukarıdaki PL/SQL bloğu çalıştırıldığında, aynen önceki örnekte olduğu gibi bir sonuç elde
edilir:

Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

101 BURAK

105 BEGUM

120 SELIN

110 DILAY

130 SEZIN

160 AHMET

200 ALI

150 AYBIKE

155 AYSE

250 ERSIN

300 HALIT

140 DILARA

350 ORCUN

8.10 Parametrelerin Kullanımı


İmleçlerin açılması ve ardından çalıştırılması esnasında, dışarıdan bir parametrenin
geçirilmesi söz konusu olabilir. Böylece imleçlerin daha esnek uygulamalarda yer alması
sağlanabilir. Bir imlece parametre geçirilmesi isteniliyorsa, aşağıda gösterildiği biçimde
tanımlanması gerekecektir:

242
İmlece geçirilecek parametre bu şekilde tanımlandıktan sonra OPEN deyimi içinde sorguya
geçirilecek değer tanımlanır.

OPEN imleç_adı(değer);

Örnek

personel isimli veri tabanı tablosunda bölüm numarası 10 olan personeli seçerek
listelemek istiyoruz.

! Amacımıza uygun PL/SQL programını görmek için “Program” düğmesine tıklayınız.

DECLARE
v_no personel.personel_no%TYPE;
v_adi personel.adi%TYPE;
-- imlecin tanıtılması....
CURSOR per_imlec (v_bolum NUMBER)
IS
SELECT personel_no, adi
FROM personel
WHERE bolum_no=v_bolum;
BEGIN
-- imlecin açılması ve parametre değerinin
-- imlece geçirilmesi...
OPEN per_imlec(10);
-- imleç değerlerinin okunarak değişkenlere
-- atanması..
LOOP
FETCH per_imlec INTO v_no, v_adi;
EXIT WHEN per_imlec%NOTFOUND;
-- sonuçların görüntülenmesi…
DBMS_OUTPUT.PUT_LINE (v_no|| ' '||v_adi);
END LOOP;
-- imlecin kapatılması..
CLOSE per_imlec;
END;

Bu blok çalıştırıldığında personel tablosunda bölüm numarası 10 olan personel isimleri ve


numaraları listelenir.

243
Blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

101 BURAK

105 BEGUM

120 SELIN

244
245
246
247
KURAL DIŞI DURUMLARIN DENETLENMESİ

Bu bölümde;

• Kural Dışı Durumların Denetimi


• Kural Dışı Durumların Yakalanması
• Önceden Tanımlı Sunucu Hatalarının
Yakalanması
• Önceden Tanımlı Olmayan Sunucu Hatalarının
Yakalanması
• Sunucu Hata Kodlarının Belirlenmesi
• Kullanıcı Tanımlı Hata Denetimi

anlatılmaktadır.

Bölüm Hedefi
Bu bölümde aşağıda sıralanan konular ele alınarak
incelenecektir:

• Kural Dışı Durumlar Nelerdir?


• Kural Dışı Durumların Denetlenmesi
• Önceden Tanımlı Sunucu Hataların Yakalanması
• Önceden Tanımlı Olmayan Sunucu Hatalarının
Yakalanması
• Sunucu Hata Kodlarının Belirlenmesi

• Kullanıcı Tanımlı Hata Denetimi

9.1 Kural Dışı Durumların Denetimi


PL/SQL blokları içinde kural dışı durumları denetleme gereksinimi ortaya çıkabilir. Hata
durumları da bir kural dışı durum olarak değerlendirilir. PL/SQL blokları çalıştırıldığında,
doğal olarak bazı hatalar ortaya çıkabilir. Örneğin, personel tablosunda bir personel
aranıldığında söz konusu tablo içinde bu personele ilişkin bir kayıt olmayabilir. Böyle
durumları denetim altına almak gerekmektedir. İşte bu tür kural dışı durumları denetleme
işlemlerini yerine getirmek üzere PL/SQL'in bazı olanakları bulunmaktadır.

PL/SQL bloklarında kural dışı durumlar BEGIN içinde tanımlanır. Bir kural dışı durum
ortaya çıktığında bunu çözümlemek ve ne yapılacağını tanımlamak üzere EXCEPTION
bloğu içinde bir tanım yapmak gerekecektir.

248
PL/SQL bloklarında kural dışı durumların denetlenmesi önemli bir konudur. Bu sayede
programların daha iyi denetlenmesi sağlanır. Blok çalıştırıldığında bir kural dışı durum ile
karşılaşıldığında, programın akışı bu noktadan itibaren EXCEPTION içindeki deyimlere
aktarılır ve böylece, bloğun çalışması EXCEPTION içindeki deyimlerin çalışması ardından
sona erer. Böylece BEGIN içinde kural dışı durumun ortaya çıktığı noktadan sonraki BEGIN
deyimleri işlem görmez.

9.2 Kural Dışı Durumların Yakalanması


Kural dışı durumlar PL/SQL bloğunun EXCEPTION bölümünde tanımlanır. Bu tanım
aşağıda gösterildiği biçimde yapılır:

WHEN anahtar kelimesi kural dışı durum ortaya çıktığında ne yapılacağını tanımlar. Birden
fazla WHEN kullanılabilir. WHEN OTHERS ise WHEN ile tanımlanan durumun dışında kalan
kural dışı durumlarda neler yapılacağını belirler.

Örnek

249
Bir tabloda aranılan kayıt bulunamadığında, NO_DATA_FOUND isimli kural dışı durum ortaya
çıkar. Bu durumu denetleyerek bir mesaj üretmek üzere aşağıdaki PL/SQL bloğunu
yazıyoruz:

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
v_adi personel.adi%TYPE;
BEGIN
-- tablodan okunan veriler değişken
-- içine yerleştiriliyor..
SELECT adi
INTO v_adi
FROM personel
WHERE personel_no=999;
-- personel adı görüntüleniyor..
DBMS_OUTPUT.PUT_LINE (v_adi);
EXCEPTION
-- kural dışı durum tanımlanıyor...
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('Kayıt bulunamadı.');
END;

Bu blok, 999 numaralı personelin adını görüntülemek üzere tanımlanmıştır. Ancak bu


numaraya sahip bir personel bulunmamaktadır. O nedenle, bir kural dışı durum ortaya
çıkmıştır. SELECT deyimi aranan kaydı bulamadığı için NO_DATA_FOUND durumu ortaya
çıkmıştır. Bu durumu EXCEPTION bölümündeki WHEN deyimi algılar ve aşağıdaki mesajı
görüntüler.

Kayıt bulunamadı..

9.3 Önceden Tanımlı Sunucu Hatalarının Yakalanması


Kural dışı durumlar çoğu kez standart özelliklere sahiptir. Örneğin bir veri tabanı
tablosunda aranılan kayıt bulunamıyorsa, bunun için özel birtakım tanımlara gerek
yoktur. Bu durum veri tabanı sunucusu tarafından zaten denetlenmekte ve
NO_DATA_FOUND durumu ortaya çıkmaktır. Bunun gibi, veri tabanı sunucusu tarafından
üretilen çok sayıda hazır kural dışı durumlar bulunmaktadır. Bu durumların EXCEPTION
bölümünde WHEN ile doğrudan denetlenmesi mümkündür. Aşağıdaki tablo söz konusu
hazır kural dışı durum tanımlarının bazılarını içermektedir.

250
251
!Kural dışı durumlara ait iki örnek aşağıda verilmiştir. Örnekleri görmek için düğmelere
tıklayınız.

Örnek 1 Aşağıdaki PL/SQL bloğunu göz önüne alalım.

PL/SQL bloğunu görmek için linke tıklayınız.

Aşağıdaki PL/SQL bloğunu göz önüne alalım.

DECLARE
v_adi personel.adi%TYPE;
BEGIN
-- tablodan okunan veriler değişken içine
-- yerleştiriliyor..
SELECT adi
INTO v_adi
FROM personel;
-- personel adı görüntüleniyor..
DBMS_OUTPUT.PUT_LINE (v_adi);
EXCEPTION
-- kural dışı durum tanımlanıyor...
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Kayıt bulunamadı..');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Birden fazla kayıt..');
END;

Bu program çalıştırıldığında bir kural dışı durum ortaya çıkarak,

252
Birden fazla kayıt..

mesajının görüntülenmesine neden olacaktır. Çünkü, SELECT deyimi içinde herhangi bir
kısıt olmadığı için birden fazla kayıt seçilecektir. Bu tür bir uygulamada, SELECT deyiminin
sadece bir kayıt seçmesi beklenir. Buna karşılık, çok sayıda kayıt seçildiği için
TOO_MANY_ROWS durumu ortaya çıkmıştır.

Örnek 2

Programda belirtilen hazır kural dışı durumları kullanabildiğimiz gibi, söz konusu kural dışı
durumun türünü belirtmeden de denetleme yapabiliriz. Aşağıdaki örnek bu amaçla
hazırlanmıştır. Bu örnekte SELECT deyimi birden fazla satır seçtiği için bir kural dışı durum
ortaya çıkmıştır. Bunun için, önceki örnekte olduğu gibi TOO_MANY_ROWS hazır kural dışı
durum ifadesini kullanabiliriz. Bunun yerine, WHEN OTHERS ifadesini kullanarak sadece bir
hata ortaya çıktığını algılamak istiyoruz. Böyle bir amaca ulaşamak için aşağıdaki PL/SQL
bloğunu hazırlıyoruz.

Bu amaç ile hazırlanan PL/SQL bloğunu görmek için linke tıklayınız.

Aşağıdaki PL/SQL bloğunu göz önüne alalım.

DECLARE
v_adi personel.adi%TYPE;
BEGIN
-- tablodan veriler okunuyor..
SELECT adi
INTO v_adi
FROM personel;
-- personel adı görüntüleniyor..
DBMS_OUTPUT.PUT_LINE (v_adi);
EXCEPTION
-- kural dışı durum tanımlanıyor...
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Kayıt bulunamadı..');

WHEN OTHERS THEN


DBMS_OUTPUT.PUT_LINE ('Programda hata var..');
END;

Bu blok çalıştırıldığında şu şekilde bir sonuç görüntülenir:

Programda hata var..

9.4 Önceden Tanımlı Olmayan Sunucu Hatalarının


Yakalanması
Önceki kısımda bazı kural dışı durumların özel ifadelerle nasıl tanımlanabildiğini gördük.
Örneğin, bir veri tabanı tablosunda aradığımız kayıtın bulunamaması halinde
NO_DATA_FOUND durumunun otomatik olarak ortaya çıktığını ve bu durumu EXCEPTION
bölümünde denetleyebildiğimizi biliyoruz.

253
Bu özel ifadeler veri tabanı sunucusunun iç hata kodlarına karşılık gelmektedir. Ancak bu
kodlar yerine özel isimleri kullandık. Bu özel kural dışı durumlar dışında daha pekçok
kural dışı durum mevcuttur. Söz konusu kural dışı durumları da denetlemek mümkündür.

Örnek

bölüm ve personel tabloları arasında bir ilişkisel bütünlük (referential integrity)


sınırlaması olduğunu varsayalım. Bunun anlamı, bölüm tablosunda her kayıdı
istediğimizde silme imkanımızın olmadığını göstermektedir. Örneğin, 10 numaralı
bölümde personel varsa, bölüm tablosundan bu kaydı silemeyiz. Böyle bir silme işlemi
yapılmaya çalışıldığında veri tabanı sunucusu bir hata mesajı üretecektir. Bu hata
mesajının kodu -2292 dir. Aşağıdaki PL/SQL bloğu böyle bir silme işlemini denemektedir.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- kural dışı durum tanımlanıyor…
h_bolum_no EXCEPTION;
PRAGMA EXCEPTION_INIT (h_bolum_no, -2292);
BEGIN
-- veritabanından bazı kayıtlar siliniyor..
DELETE FROM bolum
WHERE bolum_no=10;
COMMIT;
EXCEPTION
-- kural dışı durum yakalanıyor…
WHEN h_bolum_no THEN
DBMS_OUTPUT.PUT_LINE ('Kayıt silemezsiniz..');
END;

254
Bu blok çalıştığında, 10 numaralı bölüm silinemez. Çünkü bu tabloyla ilişkili olan
personel tablosunda 10 numaralı bölümde çalışan personel bilgileri yer almaktadır. O
halde bu bölümü bolum tablosundan silemeyiz. Böyle bir durumda, veri tabanı sunucusu
-2292 numaralı hata kodunu üretir. Bu hata kodunu, DECLARE bölümünde tanımlamıştık.
EXCEPTION bölümünde ise WHEN deyimi ile bu hata kodu algılanır ve aşağıda görüldüğü
biçimde bir mesaj yayınlanır:

Kayıt silemezsiniz..

9.5 Sunucu Hata Kodlarının Belirlenmesi


Kural dışı bir durumla karşılaşıldığında, veri tabanı suınucusunun bir hata kodu ürettiğini
biliyoruz. O halde bu kodu elde etme imkanımız var mıdır? Söz konusu hata kodunu
öğrenmek için,

SQLCODE

fonksiyonları kullanılabilir. Bu koda ilişkin hata mesajını elde etmek gerektiğinde ise,

SQLERRM

fonksiyonuna başvurulur. SQLCODE fonksiyonu, bir tablodan kayıt okunamama


durumunda, yani NO_DATA_FOUND kural dışı durumu ortaya çıktığında +100 hata kodunu,
bunun dışında kalan durumlarda ise negatif bir hata kodunu üretir.

Örnek 1

Bu örnekte SELECT deyimi birden fazla satır seçtiği için bir kural dışı durum ortaya
çıkmıştır. Bunun için, önceki örnekte olduğu gibi TOO_MANY_ROWS hazır kural dışı durum
ifadesini kullanabiliriz. Bunun yerine, WHEN OTHERS ifadesini kullanarak ORACLE veri
tabanı sunucusunun kendi hata mesaj kodunu ve bu mesaj ifadesini elde etmek istiyoruz.

255
Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
v_adi personel.adi%TYPE;
BEGIN
-- tablodan veriler okunuyor..
SELECT adi
INTO v_adi
FROM personel;
-- personel adı görüntüleniyor..
DBMS_OUTPUT.PUT_LINE (v_adi);
EXCEPTION
-- kural dışı durum ortaya çıktığında
-- hata kodu ve hata mesajı görüntülenecektir..
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (SQLCODE);
DBMS_OUTPUT.PUT_LINE (SQLERRM);
END;

Bu program çalıştırıldığında, ortaya çıkan hatalı duruma uyan ORACLE veri tabanı sunucu
hata kodu ve hata ifadesi görüntülenir.

Bu blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız

-1422
ORA-01422: <hata mesajı...

Örnek 2

personel tablosundan 999 numaralı personelin adını okumak istiyoruz. Ancak söz konusu
tabloda böyle bir numaraya sahip personel bulunmamaktadır. Bu kural dışı durum ile ilgili
olarak ORACLE sunucusunun ürettiği hata kodunu ve mesajını öğrenmek istiyoruz.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
v_adi personel.adi%TYPE;
BEGIN
-- tablodan veriler okunuyor..
SELECT adi
INTO v_adi
FROM personel
WHERE personel_no=999;
-- personel adı görüntüleniyor..
DBMS_OUTPUT.PUT_LINE (v_adi);
EXCEPTION
-- kural dışı durum ortaya çıktığında
-- hata kodu ve hata mesajı görüntülenecektir..
WHEN OTHERS THEN

256
DBMS_OUTPUT.PUT_LINE (SQLCODE);
DBMS_OUTPUT.PUT_LINE (SQLERRM);
END;

Bu program çalıştırıldığında, ortaya çıkan hatalı duruma uyan ORACLE veri tabanı sunucu
hata kodu ve hata ifadesi görüntülenir.

Bu blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız.

100
ORA-01403: hiç bir veri bulunmadı

9.6 Kullanıcı Tanımlı Hata Denetimi


PL/SQL ‘de kullanıcı tarafından tanımlanan kural dışı durumları denetleme imkanı
bulunmaktadır. Bu tür kural dışı durumları tanımlamak için aşağıda belirtilen yol izlenir:

Örnek 1

personel tablosunda 999 numaralı personelin ücret bilgisini 8900 olarak değiştirmek
istiyoruz. Bu işlemin yapılabilmesi için doğal olarak ilgili personelin personel tablosunda
kayıtlı olması beklenir. Eğer ilgili personel bulunamaz ise bir uyarı mesajı
görüntülenecektir. Bu tür kural dışı durumu denetlemek için NO_DATA_FOUND hazır
tanımları kullanılabilir. Ancak biz bu yola başvurmadan kendi kodlarımıza bu durumu
ortaya koymak istiyoruz.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- Kural dışı durum adı tanımlanıyor..
h_gecersiz EXCEPTION;
BEGIN
-- veri tabanı tablosu güncelleştiriliyor..
UPDATE personel

257
SET ucret= 8900
WHERE personel_no=999;
-- SQL in kayıt bulunamadı mesajı üretilmiş ise
-- kural dışı durumu ortaya çıkarılıyor..
IF SQL%NOTFOUND THEN
RAISE h_gecersiz;
END IF;
COMMIT;
EXCEPTION
WHEN h_gecersiz THEN
DBMS_OUTPUT.PUT_LINE ('Geçersiz personel no..');
END;

Bu blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız.

Geçersiz personel no..

Örnek 2

PL/SQL bloğu içinde iki sayısal değeri topladıktan sonra, sonuç negatif ise bunu bir kural
dışı durum olarak kabul edip, sonucu bir mesaj ile duyuralım istiyoruz.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
sayi_1 NUMBER :=5;
sayi_2 NUMBER :=-7;
sonuc NUMBER;
-- Kural dışı durum adı tanımlanıyor..
hata EXCEPTION;
BEGIN
sonuc := sayi_1 + sayi_2;
-- kural dışı durumu ortaya çıkarılıyor..
IF sonuc < 0 THEN
RAISE hata;
END IF;
EXCEPTION
WHEN hata THEN
DBMS_OUTPUT.PUT_LINE ('Sonuç negatif..');
END;

Bu blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız.

Sonuç negatif..

258
259
260
261
ALTPROGRAMLAR

Bu bölümde;

• Altprogram
• PL/SQL Modüllerinin Ortak Yapıları
• Yordamlar
• Fonksiyonlar
• Paketler

anlatılmaktadır.

Bölüm Hedefi
Bu bölümde aşağıda sıralanan konular ele alınarak
incelenecektir:

• Alt Program veya Modül Nedir?


• PL/SQL Modüllerinin Ortak Yanları
• Yordamlar
• Saklı Yordamlar
• Fonksiyonlar
• Saklı Fonksiyonlar

• Paketlerin Yaratılması

10.1 Altprogram Nedir ?


Modüler kodlama; bir programı, her biri ayrı işlevleri yerine getiren ve birbirinden ayrı alt
programlardan oluşturma metodolojisidir. Bu yaklaşım biçimi yazılımlara bir çok açıdan
yarar sağlamaktadır.

PL/SQL programları da modüler kodlamaya uygundur. PL/SQL blokları aslında birer modül
olarak değerlendirilir. Daha önceki konularda ele alarak incelediğimiz anonim bloklar birer
modül olarak söz önüne alınır. Modüllere “altprogram” adı da verilebilir. PL/SQL
altprogramlarını şu şekilde sıralamız mümkündür:

• Anonim bloklar
• Yordamlar (procedures)
• Fonksiyonlar
• Paketler (packages)

262
Önceki bölümlerde anonim blokları ele alarak incelemiştik. Bu tür blokların aşağıda
sıralanan özelliklere sahip olduğunu biliyoruz:

• Anonim bloklar isimlendirilmez.


• Adı olmadığı için, bir diğer bloktan çağrılamaz.
• Veri tabanında saklı değildir.
• Her çağrıldığında yeniden derlenerek çalışır.

10.2 PL/SQL Modüllerinin Ortak Yapıları


PL/SQL modüllerinin yapısı birbirine benzer. Aşağıda bu ortak yanları sıralıyoruz:

a. Başlık: Sadece bir isime sahip olan modüllerde bu kısım kullanılır. Başlık kısmında
aşağıda sıralanan öğreler yer alır:
o Modül adı
o Parametre listesi
o RETURN deyimi. Bu deyim sadece fonsiyonlarda vardır.
b. DECLARE bölümü aşağıda sıralanan öğrelere sahip olabilir:

263
o Değişken tanımları
o İmleç tanımları
o Alt bloklar
c. BEGIN bölümünde aşağıda yer alan işlemlere başvurulabilir:
o Atama işlemleri
o IF-THEN-ELSE karar işlemleri
o Döngü işlemleri
o Diğer PL/SQL bloklarını çağırma işlemleri
d. EXCEPTION bölümünde ise aşağıda sıralanan işlemler yerine getirilir:
o Kural dışı durumları yakalama işlemleri

10.3 Yordamlar
PL/SQL programlarında yer alabilecek bir değer modül türü yordam (procedure) olarak
bilinmektedir. Yordam, bir veya daha fazla eylemi yerine getirmek üzere oluşturulan
yapılardır. Çağrıldığında herhangi bir değer döndürmez, sadece verilen görevi yerine
getirir. Bu yönü göz önüne alındığında fonksiyonlardan farklı olduğunu söyleyebiliriz.
Yordam, aslında bir PL/SQL bloğudur. Belirli bir yapısı vardır. PL/SQL yordamları
oluşturulma ve kullanma açısından iki farklı türü bulunmaktadır. Bunlar yanda
verilmektedir.

Sözünü ettiğimiz bu yordam türlerini ele alarak incelemek istiyoruz.

264
10.3.1 Anonim Blok İçinde Kullanılan Yordamlar
Anonim bloklar içinde bir veya daha fazla yordam yer alabilir. Bu yordamlar belirli bir
yapıya sahiptir. Bir yordam şu şekilde kullanılabilir:

PROCEDURE yordam adı (parametre listesi) IS


[yerel bildirimler]
BEGIN
deyimler;
[EXCEPTION
deyimler;
END yordam adı;

Görüldüğü gibi, yordamın bir ismi olmalıdır. Bu isime dayanılarak, söz konusu yordam
PL/SQL bloklarının BEGIN bölümünde çağrılarak kullanılabilir. Yordamlar PL/SQL
bloklarının DECLARE bölümünde tanımlanır.

Örnek

personel tablosundan belirli personelin isimlerini seçerek görüntüleyen bir PL/SQL


programı yazmak istiyoruz.

Amacımıza uygun bir SELECT deyimini test isimli bir yordam içinde şu şekilde
tanımlıyoruz:

PROCEDURE test (p_no NUMBER) IS


v_adi personel.adi%TYPE;
BEGIN
-- tablodan veriler okunuyor...
SELECT adi
INTO v_adi
FROM personel
WHERE personel_no=p_no;
-- personel adı görüntüleniyor..
DBMS_OUTPUT.PUT_LINE (v_adi);

265
END test;

Bu yordamda şu tanımlar yer almaktadır:

Yordamın adı: test

Parametre : p_no

Yukarıdaki yordamı çalıştırabilmek için, örneğin 101 numaralı personel ilişkin olarak
sorgulama yapabilmek için,

test(101);

biçiminde kullanmak gerekiyor. Diğer personeli de sorgulamak için benzer tanım yapılır.
Buraya kadar söylediklerimizi bir PL/SQL bloğu içinde aşağıda gösterildiği biçimde
birleştirerek sunuyoruz:

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- yordam tanımlanıyor...
PROCEDURE test (p_no NUMBER) IS
v_adi personel.adi%TYPE;
BEGIN
-- tablodan veriler okunuyor...
SELECT adi
INTO v_adi
FROM personel
WHERE personel_no=p_no;
-- personel adı görüntüleniyor..
DBMS_OUTPUT.PUT_LINE (v_adi);
END test;
BEGIN
-- yordam ardarda üç kez çalıştırılıyor..
test(101);
test(105);
test(120);
END;

Bu blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız.

BURAK

BEGUM

SELIN

10.3.2 Saklı Yordamlar

266
Önceki kısımda ele aldığımız yordamların en önemli özelliği, bir anonim PL/SQL bloğunun
içinde yer almasıdır. Bu tür yordamları sadece o anonim blok tarafından kullanılabilir
çünkü anonim blok ve yordam aynı programın birer parçasıdır.

Uygulamada çoğunlukla saklı yordamlar (stored procedures) kullanılır. Bu tür yordamlar


belirli bir isimle veri tabanı içinde saklıdırlar. Yordamlar derlenir. Böylece saklı yordamlar,
bir veri tabanı nesnesi olarak değerlendirilir.

Herhangi bir PL/SQL bloğundan ya da bir diğer dış uygulamadan, örneğin bir ASP
programından ya da Visual Basic programından çağrılarak kullanılabilirler. O nedenle saklı
yordamlar uygulama geliştiriciler açısından önemli kavramlardır.

10.3.2.1 Saklı Yordamların Yaratılması


Bir saklı yordamın yaratılması için belirli işlemlerin yapılması gerekmektedir. Aşağıdaki
deyim, bu tür yordamları veri tabanı içinde yaratmak amacıyla kullanılır:

CREATE OR REPLACE PROCEDURE yordam adı (parametreler) IS


BEGIN
deyimler;
END yordam adı;

Örnek

Veri tabanında yer alan BOLUM isimli tabloya satır ekleme işlemlerini yerine getirmek
üzere bir yordam yaratmak istiyoruz. Bu yordamın adı bolum_ekle olacaktır.

! Amacımıza uygun olarak yaratılan yordamı görmek için düğmeye tıklayınız.

CREATE OR REPLACE PROCEDURE bolum_ekle


(v_no bolum.bolum_no%TYPE,
v_adi bolum.bolum_adi%TYPE,
v_konum bolum.konum%TYPE) IS
BEGIN
-- tabloya kayıt ekleme işlemi..
INSERT INTO bolum(bolum_no,bolum_adi,konum)
VALUES(v_no, v_adi, v_konum);
END bolum_ekle;

267
Yukarıdaki yordam bu şekliyle çalıştırılırsa, veri tabanında bolum_ekle isimli bir yordam
yaratılır. Bu yordam artık diğer tüm uygulamalar tarafından bolum_ekle ismi kullanılarak
çalıştırılmaya hazırdır

10.3.2.2 Saklı Yordamların Çalıştırılması


Bir saklı yordamın nasıl yaratıldığını gördük. Şimdi sıra bu yordamın çalıştırılmasına
gelmiştir. Yordamı çalıştırmak için,

yordam adı (parametreler)

biçiminde bir tanımın yapılması yeterlidir.

Örnek

Şu anda BOLUM tablosunun aşağıda görüldüğü gibi 5 adet satıra sahip olduğunu
varsayalım.

SQL> SELECT * FROM BOLUM;

BOLUM_NO BOLUM_ADI KONUM


-------- --------- --------------
10 MUHASEBE KADIKÖY
20 SATIŞ ANKARA
30 AR-GE İZMİR
40 PERSONEL KADIKÖY
50 ÜRETİM GEBZE

Bu BOLUM tablosuna bir kayıt eklemek için aşağıdaki yordamın veri tabanında yaratıldığını
varsayalım.

CREATE OR REPLACE PROCEDURE bolum_ekle


(v_no bolum.bolum_no%TYPE,
v_adi bolum.bolum_adi%TYPE,
v_konum bolum.konum%TYPE) IS
BEGIN
-- tabloya kayıt ekleme işlemi..
INSERT INTO bolum(bolum_no,bolum_adi,konum)
VALUES(v_no, v_adi, v_konum);
END bolum_ekle;

Artık bu yordam veri tabanında bolum_ekle ismiyle yer almaktadır.

Bu yordamı çağıran ve çalıştıran PL/SQL bloğunu görmek için linke


tıklayınız.

BEGIN
-- yordam iki kez ardarda çalıştırılıyor..
bolum_ekle (60,'REKLAM','KADIKÖY');
bolum_ekle (70,'SATIŞ','İZMİR');
END;

268
Yukarıdaki PL/SQL bloğunu çalıştırdığımız takdirde, BOLUM tablosuna iki adet satır ilave
edilecektir. Tablonun içeriğini yeniden görüntüleyecek olursak, sözünü ettiğimiz iki
kayıdın eklendiği görülür.

Bu blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız.

SQL> SELECT * FROM BOLUM;

BOLUM_NO BOLUM_ADI KONUM


-------- --------- --------------------
10 MUHASEBE KADIKÖY
20 SATIŞ ANKARA
30 AR-GE İZMİR
40 PERSONEL KADIKÖY
50 ÜRETİM GEBZE
60 REKLAM KADIKÖY
70 SATIŞ İZMİR

10.3.2.3 Yordamlar İçin IN ve OUT Parametreleri

Bir yordamın normal olarak bir değer döndürmediğini söylemiştik. Ancak, parametre
girişlerini yanı sıra parametre çıkışlarını da tanımlayarak bir değer döndürmesi
sağlanabilir. Bunun için yordam parametreleri ile birlikte IN ve OUT anahtar kelimeleri
kullanılabilir. Eğer bir parametre giriş parametresi olacak ise, yani çağrılan yordama bir
değer aktarılacak ise IN, çağrılan yordamdan bir değer okunacak ise parametrelerle
birlikte OUT kelimeleri kullanılır. Eğer bir parametre hem giriş, hem de çıkış amacıyla
kullanılacak ise, o parametre için IN OUT biçiminde bir tanım yapılır.

Örnek

İki sayısal değeri okuyan ve değerlendiren bir yordam yaratacağız. Bu yordamın adı test
olacaktır. Bu yordam bu iki değeri toplayacak, sonuç negatif ise “NEGATİF..” mesajını,
aksi takdirde “POZİTİF..” mesajını kendini çağıran bir anonim PL/SQL bloğuna
aktaracaktır. Sözü edilen blok, yordamdan aldığı mesajı görüntüleyecektir. Yordam şu
şekilde yaratılabilir:

CREATE OR REPLACE PROCEDURE test


(sayi_1 IN NUMBER, -- dışarıdan okunan değer..
sayi_2 IN NUMBER, -- dışarıdan okunan değer..
mesaj OUT CHAR) IS -- dışarı aktarılacak değer..
v_sonuc NUMBER;
BEGIN

269
v_sonuc := sayi_1 + sayi_2;
IF v_sonuc < 0 THEN
mesaj:= 'Negatif..';
ELSE
mesaj := 'Pozitif..';
END IF;
END test;

Bu yordam veri tabanında test ismiyle yer alacaktır. Söz konusu yordamı çağıran anonim
PL/SQL bloğunu ise şu şekilde oluşturuyoruz:

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
v_mesaj varchar2(30);
BEGIN
-- yordam çalıştırılıyor..
test(5,-7,v_mesaj);
DBMS_OUTPUT.PUT_LINE (v_mesaj);
END;

Bu blok, test yordamına 5 ve -7 sayısal değerlerini aktarmakta, yordam içinde oluşan


v_mesaj değerini okumaktadır. Sonuç şu şekilde olacaktır:

Negatif..

10.4 Fonksiyonlar
Bir diğer PL/SQL modül türü fonksiyon olarak bilinir. Fonksiyonlar aynen yordamlara
benzer. Farkı, fonksiyonların bir değer döndürmek zorunda oluşudur. Fonksiyonları iki
faklı biçimde kullanma olanağımız vardır.

10.4.1 Anonim Blok İçinde Kullanılan Fonksiyonlar


Anonim bloklar içinde bir veya daha fazla fonksiyon yer alabilir. Bu tür fonksiyonlar
aşağıda gösterildiği biçimde tanımlanırlar.

FUNCTION fonksiyon adı (parametre listesi)


RETURN veri türü
IS
BEGIN
deyimler;

270
[EXCEPTION
deyimler;
END fonksiyon adı;

Fonksiyonların yordamlardan en önemli farkı, bir değer döndürmesidir. Tanım içinde yer
alan RETURN deyimi değer döndürmek amacıyla kullanılır.

Örnek

9000, 1000 ve 5000 ücret miktarlarının, personel tablosunda yer alan en yüksek ücretten
daha büyük olup olmadığını belirlemek istiyoruz. Eğer bu değer ücretten büyük ise,
personel tablosundaki en yüksek ücret seviyesi görüntülenecektir. Aksi takdirde verilen
değer görüntülenecektir. Personel arasında en yüksek ücret miktarının 7000 olduğunu
varsayıyoruz.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

DECLARE
-- fonksiyon tanımlanıyor...
FUNCTION f_test (v_ucret IN NUMBER)
RETURN NUMBER IS
v_max_ucret NUMBER;
BEGIN
SELECT MAX(ucret)
INTO v_max_ucret
FROM personel;
IF v_ucret>v_max_ucret THEN
RETURN(v_max_ucret);
ELSE
RETURN(v_ucret);
END IF;
END f_test;
BEGIN

271
-- fonksiyon ardarda üç kez çalıştırılıyor..
DBMS_OUTPUT.PUT_LINE (f_test(9000));
DBMS_OUTPUT.PUT_LINE (f_test(1000));
DBMS_OUTPUT.PUT_LINE (f_test(5000));
END;

Bu blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız.

7000

1000

5000

10.4.2 Saklı Fonksiyonlar


Bir fonksiyon anonim bloklar içinde kullanılabileceği gibi, gerek görüldüğünde saklı
fonksiyon (stored function) biçimine dönüştürülerek diğer uygulama programlarının da
erişimi sağlanabilir. Saklı fonksiyonlar, bir isim verilerek veri tabanına yerleştirilen
fonksiyonlardır. Saklı fonksiyonlar derlenir ve birer veri tabanı nesnesi olarak
değerlendirilir.

Herhangi bir PL/SQL bloğundan yada bir diğer dış uygulamadan, örneğin bir ASP
programından yada yada VisualBasic programından çağrılarak kullanılabilirler.

10.4.2.1 Saklı Fonksiyonların Yaratılması


Bir saklı fonksiyonun yaratılması için CREATE OR REPLACE FUNCTION deyimi kullanılır. Bu
deyim bu tür fonksiyonları veri tabanı içinde yaratmak amacıyla kullanılır:

CREATE OR REPLACE FUNCTION fonksiyon adı (parametreler)

272
RETURN veri türü
IS
BEGIN
deyimler;
END fonksiyon adı;

Örnek

Önceki örneği yeniden göz önüne alalım. Bu örnekte şu amaca ulaşılıyordu: 9000, 1000
ve 5000 ücret miktarlarının, personel tablosunda yer alan en yüksek ücretten daha
büyük olup olmadığını belirlemek istiyoruz. Eğer bu değer ücretten büyük ise, personel
tablosundaki en yüksek ücret seviyesi görüntülenecektir. Aynı amaca bu kez saklı
fonksiyonları kullanarak ulaşmak istiyoruz. Bunun için aşağıda belirtilen blok hazırlanır ve
çalıştırılır.

Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

CREATE OR REPLACE FUNCTION f_test (v_ucret IN NUMBER)


RETURN NUMBER IS
v_max_ucret NUMBER;
BEGIN
SELECT MAX(ucret)
INTO v_max_ucret
FROM personel;
IF v_ucret>v_max_ucret THEN
RETURN(v_max_ucret);
ELSE
RETURN(v_ucret);
END IF;
END f_test;

Yukarıdaki yordam bu şekliyle çalıştırılırsa, veri tabanında f_test isimli bir fonksiyon
yaratılır. Bu fonksiyon artık diğer tüm uygulamalar tarafından f_test ismi kullanılarak
çalıştırılmaya hazırdır.

10.4.2.2 Saklı Fonksiyonların Çalıştırılması


Bir saklı fonksiyonun nasıl yaratıldığını gördük. Şimdi sıra bu fonksiyonun çalıştırılmasına
gelmiştir. Fonksiyonu çalıştırmak için,

fonksiyon adı (parametreler)

biçiminde bir tanımın yapılması yeterlidir.

Örnek

Önceki örnekte f_test isimli bir fonksiyon tanımlamıştık. Şimdi bu fonksiyonu


çağırabilecek bir anonim PL/SQL bloğu oluşturmak istiyoruz.

273
Bu amaç ile yazılan PL/SQL bloğunu görmek için linke tıklayınız.

BEGIN
-- fonksiyon ardarda üç kez çalıştırılıyor..
DBMS_OUTPUT.PUT_LINE (f_test(9000));
DBMS_OUTPUT.PUT_LINE (f_test(1000));
DBMS_OUTPUT.PUT_LINE (f_test(5000));
END;

Bu blok çalıştırıldığında oluşan çıktıyı görmek için linke tıklayınız.

7000

1000

5000

10.5 Paketler
Bir diğer PL/SQL modülü paket (package) olarak bilinir. Paketler veri tabanı nesneleri
olarak kabul edilir. Diğer veri tabanı nesnelerini mantıksal olarak bir grup halinde içereren
bir nesnedir. O halde bir paket, amacına uygun olarak birden fazla yordam ve fonksiyonu
içeren bir nesnedir. Bir paket belirli bir isim ile veri tabanı içinde saklanabilir. Bu sayede
aynı paketi çok sayıda uygulama aynen kullanabilecektir.

Paketler, iki parça halinde düşünülür. Bunlardan birincisi, paketin içerdiği modüllerin adını
ve parametrelerini içeren başlık kısmıdır. İkincisi ise, paketin içerdiği yordam ve
fonksiyonların ayrıntılı kodlarını, yani BEGIN ile başlayan ana kodlarını içeren kısmıdır. Bu
yöntem, güvenlik açısısından uygulamalara bazı avantajlar sağlar. Uygulama programları
sadece paketin başlık kısmıyla ilgilenir. Diğer kısımlarına uygulama programları ulaşamaz.
Sadece çalışarak görevlerini yerine getirmeleri sağlanabilir.

274
10.5.1 Paketlerin Yaratılması
Bir paketin yaratılması için belirli işlemlerin yapılması gerekmektedir. Bir paketi yaratmak
için iki deyim kullanılır:

Birinci ifade paketlerin başlık kısmını yaratmak amacıyla kullanılır. İkinci deyim ise
paketin ana kısmını yaratmak üzere kullanılır. Aşağıdaki deyim, paketin başlık kısmını
yaratır:

CREATE OR REPLACE PACKAGE paket adı


IS
yordam başlıkları..
fonksiyon başlıkları..
END paket adı;

Paketin ana kısımlarını yaratmak üzere aşağıdaki tanım kullanılır:

CREATE OR REPLACE PACKAGE BODY paket adı


IS
PROCEDURE yordam adı
(parametre listesi)
IS
BEGIN
deyimler;
END yordam adı;
FUNCTION fonksiyon adı
(parametre listesi)
RETURN veri türü
IS
BEGIN
deyimler;
END fonksiyon adı;

diğer yordam ve fonksiyonlar..


END paket adı;

Örnek

Bir paket oluşturacağız. Bu paket bir yordam ve bir fonksiyondan oluşacaktır. Yordam,
bolum tablosuna yeni bölümler eklemeyi sağlar. Fonksiyon ise bolum tablosunda kaç
bölümün kaydedildiğini görüntüler.

! Amacımıza uygun p_test isimli paketin başlık ve paketin ana kısımlarını oluşturmak için
paket düğmesine tıklayınız.

275
Amacımıza uygun p_test isimli paketin başlık kısımları şu şekilde yaratılabilir:

CREATE OR REPLACE PACKAGE p_test IS


-- Bir yordam tanımlanıyor. Bu yordam bolum
-- tablosuna yeni bir kayıt ekler...
PROCEDURE p_ekle
(v_no bolum.bolum_no%TYPE,
v_adi bolum.bolum_adi%TYPE,
v_konum bolum.konum%TYPE);
-- Bir fonksiyon tanımlanıyor. Bu fonksiyon belirli
-- bir bölümdeki personel sayısını döndürür....
FUNCTION f_sayi
(p_bolum NUMBER)
RETURN NUMBER;
END p_test;

Paket bu şekilde oluşturulduktan sonra çalıştırılırsa, bir veri tabanı nesnesi olarak veri
tabanı içine kaydedildiği görülür. Bu işlemin ardından paketin ana kısımları oluşturulur:

CREATE OR REPLACE PACKAGE BODY p_test IS


-- Yordamın ana kodları tanımlanıyor…
PROCEDURE p_ekle
(v_no bolum.bolum_no%TYPE,
v_adi bolum.bolum_adi%TYPE,
v_konum bolum.konum%TYPE) IS
BEGIN
-- tabloya kayıt ekleme işlemi..
INSERT INTO bolum(bolum_no,bolum_adi,konum)
VALUES(v_no, v_adi, v_konum);
END p_ekle;
-- Fonksiyounun ana kodları tanımlanıyor…
FUNCTION f_sayi (p_bolum IN NUMBER)
RETURN NUMBER IS
v_sayi NUMBER;
BEGIN
-- Kayıtlar sayılıyor...
SELECT COUNT(*)
INTO v_sayi
FROM personel
WHERE bolum_no = p_bolum;
RETURN(v_sayi);
END f_test;
END p_test;

Paket bu şekilde oluşturulduktan sonra çalıştırılırsa, paketin ana kısmı da veri tabanı
üzerinde yaratılmış olur.

10.5.2 Paketlerin Çalıştırılması


Paketler oluşturulduktan sonra, bir anonim blok içinde ya da bir uygulama programı
içinde çağrılarak çalıştırılır. Ancak paket, içinde hangi modülün çalıştırılacağını belirlemek
için aşağıda gösterildiği biçimde kullanılır:

276
paket adı.modül adı(parametreler);

Örnek

Bir anonim blok içinde yer alan p_test yordamı f_test fonksiyonu aşağıda gösterildiği
biçimde çalıştırılabilir:

BEGIN
/* p_test isimli yordam içindeki p_ekle yordamı
ve f_test fonksiyonu çalıştırılıyor..
f_test fonksiyonu, 10 numaralı bölümdeki
personel sayısını verecektir.. */

p_test.bolum_ekle (60,'REKLAM','KADIKÖY');
DBMS_OUTPUT.PUT_LINE (p_test.f_test(10));
END;

277
278
279
280
DERS SONU
İleri Veri Tabanı Sistemleri dersinin sonuna gelmiş bulunmaktayız. Bu
çalışmamızın tüm öğrencilerimize faydalı olması dileğiyle...

Sınavlarınızda başarılar...Dr. Yalçın Özkan

281

You might also like