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 FROM SQL'in sorgulama deyimidir. Hangi tablonun sorgulanacağını ifade eder.

10

DISTINCT

Çift kayıtları önleyen anahtar 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_adı Bölüm numarasıdır. Bölümün adıdır.

12

Konumu

Bölümün bulunduğu 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

tıklayınız.

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

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

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

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

Ö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 sütun ifade argümanlar

Herhangi bir SQL fonksiyonunu simgeler. Örneğin LOWER bir fonksiyon ismidir. Bu ismi değiştiremeyiz. Herhangi bir tabloya ilişkin sütun adı 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 YYYY YEAR MM MONTH DD DY DAY Anlamı Dört haneli yıl bilgisi. Örneğin; 2002 Yılın rakamlarla değil, okunduğu gibi yazılması İki haneli ay bilgisi Ayın tam adı İki haneli gün bilgisi Haftanın günü. Üç karakterden oluşur. Günün tam adı

58

Zamanla ilgili biçimlendirme ifadeleri ise aşağıdaki elemanlardan oluşabilir; Eleman AM,PM HH MI SS Anlamı Meridyen göstergesi Günün saati Dakika bilgisi Saniye bilgisi

Sayısal değerleri kullanan TO_CHAR() fonksiyonu, aşağıdaki tabloda yer alan biçimlendirme elemanlarını kullanabilir; Eleman 9 0 $ L . , Ö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; Anlamı Sayısal değeri ifade eder. Sıfır değerini ifade eder. Dolar işaretini yerleştirir. Yerel para işaretini yerleştirir. Ondalık hanesini gösterir. Binler hanesini gösterir.

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 0 $ L . , Sayısal değeri ifade eder. Sıfır değerini ifade eder. Dolar işaretini yerleştirir. 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: • • • Ö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 ); WHERE HAVING FROM

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. c.
Yani ana sorgunun WHERE koşulu şu şekli almış olacaktır: WHERE ÜCRET > 5000 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. 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.

b)

120

Veri tabanlarında iki türlü tablo yer almaktadır: Bu tablolar herhangi bir veri tabanı kullanıcısı tarafından yaratılan tablolardır. Söz konusu tabloların isimleri ve sütunları doğal olarak 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ü (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.

Kullanıcı tabloları

Veri sözlüğü

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ı 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.

b)

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 tablo sütunlar veri türü DEFAULT ifade Tablonun sahibini belirler Yaratılacak tablonun adı Tablonun herbir sütunu Herbir sütunun veri türü Sütuna veri girişi yapılmadığında, o sütunun 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 adını içerecektir. En fazla 15 karakter olabilir. Bölümün yerini belirleyecekitir. En fazla 13 karakter olabilir.

BÖLÜM_ADI

KONUM

Bu tablo aşağıda belirtildiği biçimde yaratılabilir: CREATE TABLE BÖLÜM (BÖLÜM_NO BÖLÜM_ADI KONUM

NUMBER(2), VARCHAR2(15), 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.

tıklayınız.

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

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); tablo sütunlar Kayıt ekleme işleminin yapılacağı tablonun adı. 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 numarası : 70

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

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> SQL> 2 3 4 VARIABLE x NUMBER; BEGIN :x:=100; END; /

! 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

END;

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

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 durum

NUMBER(5) :=0; 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 durum

NUMBER DEFAULT 0; 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 durum

NUMBER(5) NOT NULL :=0; 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 bolum_tutar

REAL(9,2); REAL(9,2);

Bu tanım yerine %TYPE kullanarak şu şekilde bir bildirim yapılabilir: DECLARE tutar bolum_tutar Ö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.

REAL(9,2); TUTAR%TYPE;

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ü VARCHAR2(boyut)

Anlamı 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. Belirlenen boyuttaki sabit uzunluklu karakter verileri ifade etmekte kullanılır. Varsayılan değer 1, en uzun boyutu ise 2000 karakterdir. 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. Tarih ve zaman verilerini ifade etmekte kullanılır. Değişken uzunluklu karakter veriyi ifade eder. Boyutu 2 gigabayt kadar olabilir. 4 gigabayta kadar karakter verileri ifade eder. Boyutu belirlenmiş ikili (binary) verileri ifade etmekte kullanılır. En büyük boyutu 2000 olabilir. 2 gigabayta kadar boyuta sahip değişken uzunluklu ikili verileri ifade etmekte kullanılır. 4 gigabayta kadar ikili verileri ifade eder. Bir dış dosyada saklanan ikili verileri belirtir. 4 gigabayt kadar bir büyüklüğe sahip olabilir.

CHAR(boyut)

NUMBER(p,s)

DATE LONG

CLOB RAW(boyut)

LONG RAW

BLOB BFILE

175

Örnek Aşağıdaki bildirimler bölümünde çeşitli veri türleri tanımlanmaktadır: DECLARE adi personel_no ucret adres dogum_tar

VARCHAR2(20); BUNBER(8); NUMBER(7,2); VARCHAR2(200); 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.

tıklayınız.

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

Ö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.

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

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

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

1 2 3 4 5

Ö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

0 1 2 3 4 5

Ö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

… EXIT son1 WHEN …. END LOOP; … END LOOP son1;

… LOOP

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

END;

SELECT MAX(ucret) INTO ucret_tab(1) FROM PERSONEL; DBMS_OUTPUT.PUT_LINE (ucret_tab(1));

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

BEGIN

-- tablo tanımlanıyor.. TYPE test_turu IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; test_tab test_turu;

215

END;

-- 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);

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; -- 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;

BEGIN

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 %ISOPEN %NOTFOUND %FOUND %ROWCOUNT Ö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. Veri türü BOOLEAN BOOLEAN BOOLEAN NUMBER Anlamı İmleç açık ise TRUE döndürür. En son FETCH işlemi bir satır döndürmemiş ise TRUE döndürür. En son FETCH işlemi bir satır döndürmüş ise TRUE döndürür. Şimdiye dek döndürülen satırların sayısını verir.

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

END;

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;

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

END;

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;

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 ---------101 105 120 110 130 160 200 150 155 250 300 140 350 P_ADI ---------BURAK BEGUM SELIN DILAY SEZIN AHMET ALI AYBIKE AYSE ERSIN HALIT DILARA 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

END;

DBMS_OUTPUT.PUT_LINE (SQLCODE); DBMS_OUTPUT.PUT_LINE (SQLERRM);

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

c.

d.

o Değişken tanımları o İmleç tanımları o Alt bloklar 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 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 -------10 20 30 40 50 BOLUM_ADI --------MUHASEBE SATIŞ AR-GE PERSONEL ÜRETİM KONUM -------------KADIKÖY ANKARA İZMİR KADIKÖY 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 -------10 20 30 40 50 60 70 BOLUM_ADI --------MUHASEBE SATIŞ AR-GE PERSONEL ÜRETİM REKLAM SATIŞ KONUM -------------------KADIKÖY ANKARA İZMİR KADIKÖY GEBZE KADIKÖY İ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

END;

-- fonksiyon ardarda DBMS_OUTPUT.PUT_LINE DBMS_OUTPUT.PUT_LINE DBMS_OUTPUT.PUT_LINE

üç kez çalıştırılıyor.. (f_test(9000)); (f_test(1000)); (f_test(5000));

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 DBMS_OUTPUT.PUT_LINE DBMS_OUTPUT.PUT_LINE DBMS_OUTPUT.PUT_LINE END; üç kez çalıştırılıyor.. (f_test(9000)); (f_test(1000)); (f_test(5000));

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

Sign up to vote on this title
UsefulNot useful