PL/SQL Programlama Temelleri
PL/SQL blokları, denetim akışı, koleksiyonlar, kayıtlar, imleçler, istisnalar, procedure/function/package yapıları; trigger, dinamik SQL, definer/invoker rights, package state ve dependency yönetimi üzerine ders notları.
PL/SQL, SQL'in ilişkisel sorgu modelinden farklı bir düşünme biçimi gerektiren yordamsal veri tabanı programlama katmanıdır. Blok yapısı, kapsam (scope), imleç, istisna ve altprogramlar bu eksende ele alınır.
Ünite 1: PL/SQL'e Giriş
Bu ünite, yordamcı denetim akışı ile SQL yürütmesini PL/SQL motoru ve SQL motoru arasındaki iş bölümü üzerinden ele alır.
istemci / çağıran
|
v
PL/SQL motoru
| |
| +--> denetim akışı / değişkenler / istisnalar
|
+----------> SQL motoru
|
v
tablo / indeksPL/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.
SQLPlus, Oracle ekosisteminin uzun süredir kullanılan temel istemci arayüzlerinden biridir. 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,
- imleç,
- yerel yordam,
- istisna
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 imleç sonucunun tüm satır yapısını kayıt tipi olarak kullanır.
v_personel PERSONEL%ROWTYPE;Alanlara:
v_personel.AD
v_personel.UCRETbiç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ğerKoleksiyon 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.COUNTmevcut eleman sayısını verir.
İlk ve son eleman
v_adlar.FIRST
v_adlar.LASTmevcut 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
Bu ünite, satır tabanlı işleme gerektiğinde imlecin tanımlama, açma, getirme, işleme ve kapatma yaşam döngüsünü ele alır.
tanımla
|
v
OPEN -> FETCH -> satır var mı? --evet--> işle -> FETCH
|
hayır
|
v
CLOSEİmleç kavramı
Imleç, 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. Imleç, 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 imleç yönetimini otomatik yapar.
Örtük imleç ile ilgili durum bilgileri:
SQL%FOUND
SQL%NOTFOUND
SQL%ROWCOUNT
SQL%ISOPENgibi özniteliklerle okunabilir.
Belirtilmiş imleç
Birden fazla satır üzerinde kontrollü dolaşmak için explicit imleç tanımlanabilir.
CURSOR c_personel IS
SELECT PERSONEL_NO, AD, UCRET
FROM PERSONEL
WHERE BOLUM_NO = 20;Imleç çalışma sırası
Klasik explicit imleç yaşam döngüsü:
- declare,
- open,
- fetch,
- close.
Imleç 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.
Imleç kapatma
CLOSE c_personel;Kaynakları serbest bırakır.
Imleç öznitelikleri
Explicit imleç için:
c_personel%FOUND
c_personel%NOTFOUND
c_personel%ROWCOUNT
c_personel%ISOPENkullanılabilir.
Imleç tabanlı kayıtlar
Imleç satır yapısı %ROWTYPE ile alınabilir.
v_kayit c_personel%ROWTYPE;Imleç FOR döngüsü
PL/SQL imleç 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 imleç dolaşımlarında açık OPEN/FETCH/CLOSE kullanımından daha güvenlidir.
Parametreli imleç
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
Bu ünite, çalışma zamanı hatasının normal akıştan istisna işleyicisine aktarılmasını ve transaction kararının açık bir politika olarak korunmasını ele alır.
DML / işlem
|
v
hata oluştu mu? ---- hayır ----> normal akış
|
evet
|
v
EXCEPTION handler
|
+--> bağlam ekle / dönüştür
+--> telafi et
+--> COMMIT veya ROLLBACK kararını açık bırakIstisna yönetimi
PL/SQL çalışma zamanı hatalarını istisna 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ş istisna 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ş istisna ile ilişkilendirilebilir.
Bu amaçla PRAGMA EXCEPTION_INIT kullanılabilir.
Hata kodları
PL/SQL hata bağlamında:
SQLCODE
SQLERRMile hata kodu ve hata metni elde edilebilir.
Bu bilgiler loglama ve hata dönüşümünde kullanılabilir.
Kullanıcı tanımlı istisna
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ı istisnalara dönüştürülebilir.
Hata yönetiminde transaction
Istisna 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
Bu ünite, package specification ile dış sözleşme ve package body ile uygulama ayrıntıları arasındaki sınırı yordam ve fonksiyonlar üzerinden ele alır.
çağıran kod
|
v
package specification
|
+--> dışarı açık yordam / fonksiyon sözleşmesi
|
v
package body
|
+--> uygulama ayrıntıları
+--> private yordamlar / durumAltprogram 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,
- istisna 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 deyim 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,
- imleçler,
- istisnalar,
- 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.
Ünite 7: Trigger, Dinamik SQL ve Yetki Modeli
PL/SQL altprogramları yeniden kullanılabilir iş mantığı kurar; trigger, dinamik SQL ve yetki modeli ise bu mantığın ne zaman, hangi SQL ile ve hangi güvenlik bağlamında çalışacağını belirler.
Trigger kullanım sınırı
Trigger belirli DML veya sistem olaylarında otomatik çalışan program birimidir. Satır düzeyi trigger her etkilenen satır için, statement düzeyi trigger ise deyim başına çalışabilir.
Trigger'ın görünmeyen yan etkisi tasarımı zorlaştırabilir. Bir UPDATE deyimi doğrudan görünmeyen başka tabloları değiştiriyorsa transaction davranışı kaynak koddan okunamaz hâle gelebilir. Bu nedenle trigger:
- veri bütünlüğünün deklaratif constraint ile ifade edilemediği dar durumlarda,
- audit veya türetilmiş teknik metadata gibi açık sözleşmeli işlemlerde,
- uygulama tarafından atlanmaması gereken veri tabanı sınırlarında
düşünülebilir; normal iş akışının gizli servis katmanı olarak kullanılmamalıdır.
Dinamik SQL
Tablo, sütun veya koşul yapısı çalışma zamanında belirlenmek zorundaysa native dynamic SQL kullanılabilir:
EXECUTE IMMEDIATE sql_text
USING bind_value;Veri değerleri mümkün olduğunca bind parametresi olarak geçirilmelidir. Nesne adları bind edilemediği için dinamik identifier gerekiyorsa açık allow-list ve doğrulama gerekir.
Dinamik SQL'in iki ayrı riski vardır:
- metin birleştirme nedeniyle SQL enjeksiyonu,
- derleme zamanında görülemeyen nesne ve tür hataları.
Statik SQL mümkünse statik kalmalıdır.
Definer ve invoker rights
Bir saklı programın hangi kullanıcının yetkileriyle çalışacağı güvenlik sınırıdır. Definer rights modelinde program tanımlayıcının yetkileriyle, invoker rights modelinde çağıranın yetki bağlamına daha yakın biçimde çalışır.
Yetki modeli yalnız "çalışıyor mu?" sorusuyla seçilmemelidir. En az ayrıcalık, erişilecek nesneler ve çağrı zinciri birlikte incelenmelidir.
Package state ve oturum etkisi
Package içindeki global durum oturum boyunca yaşayabilir. Connection pool kullanılan uygulamada mantıksal kullanıcı ile fiziksel veri tabanı oturumu aynı kavram değildir. Oturumda kalan package state bu nedenle sonraki çağrılara sızabilecek gizli bağlam oluşturabilir.
Kritik servislerde tercih edilen varsayım:
çağrı girdisi
+
kalıcı veri
->
sonuçolmalı; görünmeyen session state ancak açık gerekçe varsa kullanılmalıdır.
Dependency ve invalidation
Bir package, view veya türün imzası değiştiğinde ona bağımlı PL/SQL birimleri geçersiz hâle gelebilir ve yeniden derleme gerektirebilir. Şema değişikliğini yalnız DDL'nin başarıyla çalışması olarak görmek bu nedenle yeterli değildir; bağımlılık grafiği ve çalışma zamanında ilk çağrının davranışı da release planının parçasıdır.
SQL ve PL/SQL sınırında toplu işleme
PL/SQL'in güçlü olduğu alanlardan biri, veri tabanına yakın iş kurallarını çok sayıda satıra kontrollü biçimde uygulamaktır. Ancak her satır için SQL çalıştıran döngüler, PL/SQL ve SQL yürütme motorları arasında gereksiz context switch maliyeti oluşturabilir.
BULK COLLECT ve FORALL, uygun iş yüklerinde satır-satır modeli toplu işleme dönüştürür. Buna rağmen "bütün tabloyu tek seferde belleğe al" yaklaşımı doğru değildir; limitli batch'ler PGA kullanımını dengelemeye yardım eder.
Hata yönetiminde de toplu işlemin sözleşmesi açık olmalıdır: ilk hatada tüm batch geri mi alınacak, hatalı satırlar ayrı mı kaydedilecek, yoksa kısmi başarı kabul mü edilecek? Bu karar, exception bloğundan önce veri bütünlüğü tasarımının parçasıdır.
PL/SQL davranışını Oracle sözleşmesine bağlamak
PL/SQL örneklerinde dil davranışı, SQL motoru davranışı ve oturum/transaction durumu birlikte değerlendirilmelidir. COMMIT, ROLLBACK, exception ve autonomous transaction gibi kavramlar yalnız sözdizimi değil veri görünürlüğü ve hata sınırı oluşturur.
Toplu işlemlerde performans iddiası için satır sayısı, batch büyüklüğü, PGA kullanımı ve SQL çağrı sayısı ölçülmelidir. BULK COLLECT veya FORALL her durumda daha iyi değildir; veri hacmi ve hata sözleşmesi sonuca etki eder.
Üretim kodunda WHEN OTHERS THEN NULL gibi hatayı yutan desenler güvenilir değildir. İstisnanın kaydedileceği, dönüştürüleceği veya yeniden fırlatılacağı açık olmalı; transaction'ın hangi noktada tamamlandığı da çağıran katmanla uyumlu tasarlanmalıdır.
Kaynakça
- Oracle. Oracle Database PL/SQL Language Reference, 12c Release 1 (12.1). Oracle, 2013. Kaynak
- Steven Feuerstein; Bill Pribyl. Oracle PL/SQL Programming. O'Reilly Media, 2014.