PL/SQL Programlama Temelleri

PL/SQL Programlama Temelleri

PL/SQL blok yapısı, değişkenler, denetim akışı, koleksiyonlar, kayıtlar, cursor, exception, procedure, function ve package temellerini derleyen ders notları.

PL/SQL bölümü başlangıçta veri tabanı ders notlarının devamıydı. Yordamsal programlama ayrıntıları SQL'in ilişkisel sorgu modelinden farklı bir düşünme biçimi gerektirdiği için burada ayrı bir yazı olarak tuttum. Blok yapısı, scope, cursor, exception ve altprogram konularındaki özgün sıralamayı korudum.

Ünite 1: PL/SQL'e Giriş

PL/SQL ile veri tabanı programlama

PL/SQL, Oracle'ın SQL'e eklediği yordamsal programlama dilidir.

SQL bildirimseldir. PL/SQL ise SQL deyimlerini:

  • değişkenler,
  • koşullar,
  • döngüler,
  • hata yönetimi,
  • yordamlar,
  • fonksiyonlar,
  • paketler

ile birleştirir.

PL/SQL'in temel kullanım alanı veri tabanına yakın iş mantığının tanımlanmasıdır.

Blok türleri

PL/SQL'in temel çalışma birimi bloktur.

Bloklar:

  • anonim blok,
  • saklı yordam,
  • saklı fonksiyon,
  • paket,
  • tetikleyici

gibi yapılarda kullanılabilir.

Dersin ana odağı anonim bloklar, yordamlar, fonksiyonlar ve paketlerdir.

PL/SQL program yapısı

Temel blok:

DECLARE
    -- bildirimler
BEGIN
    -- çalıştırılabilir deyimler
EXCEPTION
    -- hata işleyicileri
END;
/

DECLARE ve EXCEPTION bölümleri duruma göre kullanılmayabilir. BEGIN ve END çalıştırılabilir bölümün temelidir.

Blokların çalıştırılması

PL/SQL blokları Oracle istemci araçlarından çalıştırılabilir.

Ders notlarında SQLPlus temel arayüz olarak ele alınır. Günümüzde SQLPlus halen kullanılabilir; bunun yanında SQLcl, SQL Developer ve farklı istemci araçları da aynı veri tabanı motoruyla çalışabilir.

Önemli olan istemci aracı değil, SQL ve PL/SQL kodunun sunucuda geçerli sözdizimi ve çalışma modelidir.

SQL ve PL/SQL dosyaları

SQL ve PL/SQL komutları dosyalarda saklanıp tekrar çalıştırılabilir.

Bu yaklaşım:

  • tekrarlanabilirlik,
  • sürüm kontrolü,
  • gözden geçirme,
  • dağıtım otomasyonu

açısından etkileşimli komut girişinden daha güvenlidir.

Değişkenler ve sabitler

PL/SQL değişkenleri bildirim bölümünde tanımlanır.

DECLARE
    v_ad VARCHAR2(100);
    v_sayac NUMBER := 0;
BEGIN
    NULL;
END;
/

Sabit:

c_kdv CONSTANT NUMBER := 0.20;

SQL deyimlerinin PL/SQL içinde kullanımı

PL/SQL içinde SQL doğrudan çalıştırılabilir.

Tek satır beklenen sorguda:

SELECT AD, UCRET
INTO v_ad, v_ucret
FROM PERSONEL
WHERE PERSONEL_NO = 100;

Kardinalite önemlidir. Sorgu sıfır veya birden fazla satır döndürürse istisna oluşabilir.

DML kullanımı

UPDATE PERSONEL
SET UCRET = UCRET * 1.10
WHERE BOLUM_NO = 20;

PL/SQL bloğu içindeki DML mevcut transaction bağlamında çalışır.

Transaction deyimleri

Gerektiğinde:

COMMIT;
ROLLBACK;

kullanılabilir.

Ancak yeniden kullanılabilir yordamların kendi başına COMMIT yapıp yapmaması mimari bir karardır. Transaction sınırı çoğu uygulamada üst katmanın sorumluluğunda tutulur.

Bağlı değişkenler

Bind variable, SQL metni ile değerleri ayırır.

Kavramsal olarak:

SQL yapısı + parametre değerleri

şeklinde düşünülmelidir.

Bağlı değişkenler:

  • SQL enjeksiyonu riskini azaltmada,
  • sorgu ayrıştırma maliyetini düşürmede,
  • plan paylaşımında

önemli olabilir.

Bildirimler bölümü

DECLARE bölümünde:

  • değişken,
  • sabit,
  • tür,
  • cursor,
  • yerel yordam,
  • exception

tanımlanabilir.

Varsayılan değerler

v_sayac NUMBER := 0;

veya uygun bağlamda DEFAULT kullanılabilir.

NULL denetimi

PL/SQL'de de SQL'in üç değerli mantığına dikkat edilmelidir.

IF v_deger IS NULL THEN
    ...
END IF;

%TYPE

%TYPE, değişken tipini tablo sütunundan türetir.

v_ucret PERSONEL.UCRET%TYPE;

Sütun tipi değiştiğinde kodun veri tipi tanımıyla uyumunu korumayı kolaylaştırır.

%ROWTYPE

Bir tablonun veya cursor sonucunun tüm satır yapısını kayıt tipi olarak kullanır.

v_personel PERSONEL%ROWTYPE;

Alanlara:

v_personel.AD
v_personel.UCRET

biçiminde erişilebilir.

Veri türleri

PL/SQL:

  • sayısal,
  • karakter,
  • tarih-zaman,
  • Boolean,
  • record,
  • collection

gibi türler sağlar.

SQL veri tipleriyle PL/SQL veri tipleri büyük ölçüde bütünleşmiştir ancak her tür SQL sütun tipi olarak kullanılamaz.

İfadeler ve işleçler

PL/SQL:

  • aritmetik,
  • karşılaştırma,
  • mantıksal

işleçleri destekler.

Koşullarda NULL semantiği dikkate alınmalıdır.

Açıklama satırları

Tek satır:

-- açıklama

Çok satır:

/*
  açıklama
*/

Üretim kodunda yorumlar kodun kendisinden çıkarılamayan amacı veya özel gerekçeyi açıklamalıdır.

Ünite 2: Program Denetimi

IF deyimi

IF v_ucret > 50000 THEN
    ...
END IF;

Alternatif:

IF kosul THEN
    ...
ELSIF baska_kosul THEN
    ...
ELSE
    ...
END IF;

Koşul gerçekleşmiyorsa

ELSE, diğer koşulların hiçbirinin gerçekleşmediği yolu tanımlar.

İç içe IF

Bir IF bloğu başka bir IF bloğu içerebilir.

Derin iç içe yapı okunabilirliği azaltır. Mantıksal koşullar mümkün olduğunca sade tutulmalıdır.

Temel LOOP

LOOP
    ...
END LOOP;

Çıkış koşulu yoksa sonsuz döngü oluşur.

Koşulsuz çıkış

EXIT;

döngüyü sonlandırır.

Koşullu çıkış

EXIT WHEN v_sayac >= 10;

WHILE döngüsü

WHILE v_sayac < 10 LOOP
    v_sayac := v_sayac + 1;
END LOOP;

Koşul her iterasyon öncesinde değerlendirilir.

FOR döngüsü

FOR i IN 1..10 LOOP
    ...
END LOOP;

Belirli aralıkta yineleme için uygundur.

Döngü etiketleri

İç içe döngülerde belirli döngüyü isimlendirmek ve gerektiğinde açıkça hedeflemek için etiketler kullanılabilir.

GOTO

PL/SQL GOTO deyimini destekler.

Ancak modern yapılandırılmış programlama yaklaşımında IF, CASE, döngüler ve altprogramlar çoğu durumda daha okunabilir akış sağlar. GOTO yalnız zorunlu ve açık gerekçesi olan durumlarda düşünülmelidir.

Ünite 3: PL/SQL Koleksiyonları ve Kayıtları

PL/SQL tabloları

Eski Oracle terminolojisindeki PL/SQL table kavramı güncel terminolojide ağırlıklı olarak associative array başlığı altında değerlendirilir.

Bir koleksiyon çok sayıda aynı tür değeri tek değişken altında tutar.

Kavramsal yapı:

anahtar -> değer

Koleksiyon tanımlama

Örnek:

DECLARE
    TYPE t_adlar IS TABLE OF VARCHAR2(100)
        INDEX BY PLS_INTEGER;

    v_adlar t_adlar;
BEGIN
    v_adlar(1) := 'Ali';
    v_adlar(2) := 'Ayse';
END;
/

Koleksiyonların kullanımı

Elemanlar indeks üzerinden okunur ve değiştirilir.

Koleksiyonlar PL/SQL tarafında geçici veri kümelerini yönetmek için kullanışlıdır.

Koleksiyon öznitelikleri

Yaygın collection method'ları arasında:

  • COUNT,
  • FIRST,
  • LAST,
  • DELETE,
  • EXISTS,
  • NEXT,
  • PRIOR

bulunur.

Eleman sayısı

v_adlar.COUNT

mevcut eleman sayısını verir.

İlk ve son eleman

v_adlar.FIRST
v_adlar.LAST

mevcut indeks sınırlarını verir.

Seyrek koleksiyonlarda 1..COUNT varsayımı her zaman doğru değildir.

Eleman silme

v_adlar.DELETE(2);

belirli elemanı kaldırabilir.

Kullanıcı tanımlı kayıtlar

PL/SQL record, farklı türde alanları tek mantıksal nesne altında toplar.

TYPE t_personel IS RECORD (
    personel_no NUMBER,
    ad VARCHAR2(100),
    ucret NUMBER
);

Kayıt değişkeni

v_personel t_personel;

Alan erişimi:

v_personel.ad

%ROWTYPE

Tablo satırını manuel olarak tekrar tanımlamak yerine:

v_personel PERSONEL%ROWTYPE;

kullanılabilir.

Bu yaklaşım veri tabanı şemasıyla tip uyumunu artırır.

Ünite 4: İmleçler

İmleç kavramı

Cursor, SQL deyiminin sonuç kümesi üzerinde satır satır işlem yapmaya yarayan PL/SQL mekanizmasıdır.

SQL mümkün olduğunca küme tabanlı kullanılmalıdır. Cursor, satır bazlı iş mantığı gerçekten gerektiğinde kullanılmalıdır.

Örtük imleç

Oracle, DML ve tek satırlı SQL işlemleri için örtük cursor yönetimini otomatik yapar.

Örtük cursor ile ilgili durum bilgileri:

SQL%FOUND
SQL%NOTFOUND
SQL%ROWCOUNT
SQL%ISOPEN

gibi özniteliklerle okunabilir.

Belirtilmiş imleç

Birden fazla satır üzerinde kontrollü dolaşmak için explicit cursor tanımlanabilir.

CURSOR c_personel IS
SELECT PERSONEL_NO, AD, UCRET
FROM PERSONEL
WHERE BOLUM_NO = 20;

Cursor çalışma sırası

Klasik explicit cursor yaşam döngüsü:

  1. declare,
  2. open,
  3. fetch,
  4. close.

Cursor açma

OPEN c_personel;

Sorgu yürütme bağlamını hazırlar.

Veri alma

FETCH c_personel
INTO v_personel_no, v_ad, v_ucret;

Her FETCH bir sonraki satırı alır.

Cursor kapatma

CLOSE c_personel;

Kaynakları serbest bırakır.

Cursor öznitelikleri

Explicit cursor için:

c_personel%FOUND
c_personel%NOTFOUND
c_personel%ROWCOUNT
c_personel%ISOPEN

kullanılabilir.

Cursor tabanlı kayıtlar

Cursor satır yapısı %ROWTYPE ile alınabilir.

v_kayit c_personel%ROWTYPE;

Cursor FOR döngüsü

PL/SQL cursor açma, fetch ve kapatma işlemlerini otomatik yönetebilir.

FOR r IN (
    SELECT PERSONEL_NO, AD
    FROM PERSONEL
    WHERE BOLUM_NO = 20
) LOOP
    ...
END LOOP;

Basit cursor dolaşımlarında açık OPEN/FETCH/CLOSE kullanımından daha güvenlidir.

Parametreli cursor

CURSOR c_personel(p_bolum_no NUMBER) IS
SELECT PERSONEL_NO, AD
FROM PERSONEL
WHERE BOLUM_NO = p_bolum_no;

Aynı sorgu farklı parametrelerle tekrar kullanılabilir.

Ünite 5: Kural Dışı Durumların Denetlenmesi

Exception yönetimi

PL/SQL çalışma zamanı hatalarını exception mekanizmasıyla yönetir.

Bir hata oluştuğunda normal akış durur ve uygun EXCEPTION işleyicisine geçilir.

BEGIN
    ...
EXCEPTION
    WHEN ... THEN
        ...
END;
/

Hata yönetimi güvenilir veri tabanı programlamasının temelidir.

Önceden tanımlı hatalar

Oracle bazı hata durumlarını isimlendirilmiş exception olarak sunar.

Örneğin:

  • NO_DATA_FOUND,
  • TOO_MANY_ROWS,
  • ZERO_DIVIDE,
  • DUP_VAL_ON_INDEX.
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        ...

Önceden tanımlı olmayan sunucu hataları

Belirli Oracle hata kodları kullanıcı tarafından isimlendirilmiş exception ile ilişkilendirilebilir.

Bu amaçla PRAGMA EXCEPTION_INIT kullanılabilir.

Hata kodları

PL/SQL hata bağlamında:

SQLCODE
SQLERRM

ile hata kodu ve hata metni elde edilebilir.

Bu bilgiler loglama ve hata dönüşümünde kullanılabilir.

Kullanıcı tanımlı exception

DECLARE
    e_gecersiz_ucret EXCEPTION;
BEGIN
    IF v_ucret < 0 THEN
        RAISE e_gecersiz_ucret;
    END IF;
EXCEPTION
    WHEN e_gecersiz_ucret THEN
        ...
END;
/

İşletme kuralları anlamlı exception'lara dönüştürülebilir.

Hata yönetiminde transaction

Exception yakalanması transaction'ın otomatik olarak istenen şekilde sonuçlandırıldığı anlamına gelmez.

Hata durumunda:

  • hangi değişikliklerin geri alınacağı,
  • transaction'ın kim tarafından sonlandırılacağı,
  • hatanın üst katmana aktarılıp aktarılmayacağı

tasarımın parçasıdır.

Ünite 6: Altprogramlar

Altprogram kavramı

PL/SQL'de yeniden kullanılabilir isimlendirilmiş kod bloklarına altprogram denir.

İki temel tür:

  • procedure,
  • function.

Altprogramlar:

  • tekrar eden kodu azaltır,
  • iş mantığını merkezileştirir,
  • yetkilendirme sınırı oluşturabilir,
  • uygulama ile veri tabanı arasında kararlı arayüz sağlayabilir.

Ortak yapı

Bir altprogram:

  • ad,
  • parametreler,
  • bildirimler,
  • çalıştırılabilir bölüm,
  • exception bölümü

içerebilir.

Yordamlar

Procedure bir işi yerine getirir.

CREATE OR REPLACE PROCEDURE UCRET_GUNCELLE (
    p_personel_no IN NUMBER,
    p_yeni_ucret IN NUMBER
) AS
BEGIN
    UPDATE PERSONEL
    SET UCRET = p_yeni_ucret
    WHERE PERSONEL_NO = p_personel_no;
END;
/

Anonim blok içindeki yordamlar

Bir procedure yalnız bulunduğu blok içinde kullanılmak üzere yerel tanımlanabilir.

Bu yöntem yardımcı işlemleri bölmek için kullanılabilir.

Saklı yordamlar

Şema düzeyinde oluşturulan procedure veri tabanında derlenmiş nesne olarak saklanır.

Birden fazla uygulama aynı yordamı çağırabilir.

Yordamların çalıştırılması

PL/SQL içinden:

BEGIN
    UCRET_GUNCELLE(100, 75000);
END;
/

çağrılabilir.

İstemci aracı ve sürücüye göre callable statement mekanizmaları da kullanılabilir.

IN, OUT ve IN OUT parametreleri

IN yalnız giriş değeridir.

OUT yordamın dışarı değer vermesini sağlar.

IN OUT hem giriş hem çıkış amacıyla kullanılabilir.

API tasarımında parametre yönü açık tutulmalıdır.

Fonksiyonlar

Function bir değer döndürür.

CREATE OR REPLACE FUNCTION YILLIK_UCRET (
    p_aylik_ucret IN NUMBER
) RETURN NUMBER AS
BEGIN
    RETURN p_aylik_ucret * 12;
END;
/

Saklı fonksiyonlar

Şema düzeyindeki fonksiyonlar veri tabanı nesnesidir.

Uygun koşullarda SQL ifadeleri içinde de kullanılabilir.

Fonksiyonun yan etkileri ve SQL'den çağrılma kuralları Oracle semantiğine göre değerlendirilmelidir.

Paketler

Package, ilişkili PL/SQL öğelerini tek şema nesnesi altında gruplar.

Bir paket:

  • tipler,
  • sabitler,
  • değişkenler,
  • cursor'lar,
  • exception'lar,
  • procedure'ler,
  • function'lar

içerebilir.

Paket belirtimi

Package specification dışarıdan görülebilen arayüzdür.

CREATE OR REPLACE PACKAGE PERSONEL_API AS
    PROCEDURE UCRET_GUNCELLE(
        p_personel_no IN NUMBER,
        p_yeni_ucret IN NUMBER
    );

    FUNCTION YILLIK_UCRET(
        p_aylik_ucret IN NUMBER
    ) RETURN NUMBER;
END PERSONEL_API;
/

Paket gövdesi

Package body, arayüzde belirtilen altprogramların gerçekleştirimini içerir.

CREATE OR REPLACE PACKAGE BODY PERSONEL_API AS

    PROCEDURE UCRET_GUNCELLE(
        p_personel_no IN NUMBER,
        p_yeni_ucret IN NUMBER
    ) AS
    BEGIN
        UPDATE PERSONEL
        SET UCRET = p_yeni_ucret
        WHERE PERSONEL_NO = p_personel_no;
    END;

    FUNCTION YILLIK_UCRET(
        p_aylik_ucret IN NUMBER
    ) RETURN NUMBER AS
    BEGIN
        RETURN p_aylik_ucret * 12;
    END;

END PERSONEL_API;
/

Specification ile body ayrımı, arayüz ile gerçekleştirim ayrımını sağlar.

Paketlerin kullanımı

Paket üyesi:

PERSONEL_API.UCRET_GUNCELLE(...)

biçiminde çağrılabilir.

Paketler özellikle ortak veri tabanı işlevlerini tek ad alanında toplamak için uygundur.

Paketlerin tasarım değeri

İyi tasarlanmış paket:

  • iç gerçekleştirim ayrıntılarını gizler,
  • uygulamaya dar bir API sunar,
  • tekrar kullanım sağlar,
  • erişim yetkisinin paket düzeyinde verilmesine olanak tanır,
  • ilgili fonksiyonları mantıksal olarak bir araya getirir.

Veri tabanı programlama katmanı büyüdükçe bağımsız yordamlar yerine tutarlı paket sınırları oluşturmak bakım maliyetini azaltabilir.

Bu sayfanın QR kodu