Oracle PL/SQL Tetikleyici Eğitimi: Bileşik Yerine [Örnek]
PL/SQL'de Tetikleyici Nedir?
TETİKLER tarafından tetiklenen depolanmış programlardır. Oracle tablo üzerinde ekleme, güncelleme, silme gibi DML ifadeleri yürütüldüğünde veya bazı olaylar meydana geldiğinde motor otomatik olarak çalışır. Tetikleme durumunda çalıştırılacak kod ihtiyaca göre tanımlanabilir. Tetikleyicinin tetiklenmesi gereken olayı ve yürütmenin zamanlamasını seçebilirsiniz. Tetikleyicinin amacı veritabanındaki bilgilerin bütünlüğünü korumaktır.
Tetikleyicilerin Faydaları
Tetikleyicilerin faydaları şunlardır.
- Bazı türetilmiş sütun değerlerini otomatik olarak oluşturma
- Referans bütünlüğünü güçlendirme
- Olay günlüğe kaydetme ve tablo erişimine ilişkin bilgilerin saklanması
- Denetleme
- Synctabloların düzenli kopyalanması
- Güvenlik yetkilerinin uygulanması
- Geçersiz işlemlerin önlenmesi
Tetikleyici Türleri Oracle
Tetikleyiciler aşağıdaki parametrelere göre sınıflandırılabilir.
- Sınıflandırma zamanlama
- TETİKLEMEDEN ÖNCE: Belirtilen olay meydana gelmeden önce tetiklenir.
- AFTER Trigger: Belirtilen olay meydana geldikten sonra tetiklenir.
- Tetikleyici Yerine: Özel bir tür. Daha sonraki konular hakkında daha fazla bilgi edineceksiniz. (yalnızca DML için)
- Sınıflandırma seviye
- AÇIKLAMA düzeyinde Tetikleyici: Belirtilen olay bildirimi için bir kez tetiklenir.
- SATIR düzeyinde Tetikleyici: Belirtilen olaydan etkilenen her kayıt için tetiklenir. (yalnızca DML için)
- Sınıflandırma Etkinlikler
- DML Tetikleyici: DML olayı belirtildiğinde tetiklenir (INSERT/UPDATE/DELETE)
- DDL Tetikleyici: DDL olayı belirtildiğinde tetiklenir (CREATE/ALTER)
- VERİTABANI Tetikleyicisi: Veritabanı olayı belirtildiğinde tetiklenir (LOGON/LOGOFF/STARTUP/SHUTDOWN)
Yani her tetikleyici yukarıdaki parametrelerin birleşimidir.
Tetikleyici Nasıl Oluşturulur
Aşağıda tetikleyici oluşturmaya yönelik sözdizimi verilmiştir.
CREATE [ OR REPLACE ] TRIGGER <trigger_name> [BEFORE | AFTER | INSTEAD OF ] [INSERT | UPDATE | DELETE......] ON<name of underlying object> [FOR EACH ROW] [WHEN<condition for trigger to get execute> ] DECLARE <Declaration part> BEGIN <Execution part> EXCEPTION <Exception handling part> END;
Sözdizimi Açıklaması:
- Yukarıdaki sözdizimi, tetikleyici oluşturmada mevcut olan farklı isteğe bağlı ifadeleri gösterir.
- ÖNCE/SONRA olay zamanlamasını belirleyecektir.
- EKLEYİN/GÜNCELLE/OTURUM AÇIN/OLUŞTUR/vb. tetikleyicinin tetiklenmesi gereken olayı belirtecektir.
- ON cümlesi yukarıda belirtilen olayın hangi nesne üzerinde geçerli olduğunu belirtecektir. Örneğin bu, DML Trigger durumunda DML olayının oluşabileceği tablo adı olacaktır.
- “HER SATIR İÇİN” komutu SATIR seviyesi tetikleyicisini belirleyecektir.
- WHEN yan tümcesi, tetikleyicinin tetiklenmesi gereken ek koşulu belirtir.
- Bildirim kısmı, yürütme kısmı, istisna işleme kısmı diğer kısımla aynıdır PL/SQL blokları. Bildirim kısmı ve istisna işleme kısmı isteğe bağlıdır.
:YENİ ve :ESKİ Madde
Satır düzeyindeki bir tetikleyicide tetikleyici, ilgili her satır için etkinleşir. Bazen de DML deyiminden önceki ve sonraki değerin bilinmesi gerekir.
Oracle RECORD düzeyindeki tetikleyicide bu değerleri tutmak için iki cümle sağlanmıştır. Bu cümleleri tetikleyici gövdesindeki eski ve yeni değerlere atıfta bulunmak için kullanabiliriz.
- :NEW – Tetikleyici yürütme sırasında temel tablonun/görünümün sütunları için yeni bir değer tutar
- :OLD – Tetikleyicinin yürütülmesi sırasında temel tablonun/görünümün sütunlarının eski değerini tutar
Bu cümle DML olayına göre kullanılmalıdır. Aşağıdaki tabloda hangi cümlenin hangi DML ifadesi için geçerli olduğu belirtilecektir (INSERT/UPDATE/DELETE).
INSERT | GÜNCELLEME | SİL | |
---|---|---|---|
:YENİ | GEÇERLİ | GEÇERLİ | GEÇERSİZ. Silme durumunda yeni değer yoktur. |
:ESKİMİŞ | GEÇERSİZ. Ekleme durumunda eski bir değer yok | GEÇERLİ | GEÇERLİ |
Tetikleyici Yerine
“INSTEAD OF tetikleyici” özel bir tetikleyici türüdür. Yalnızca DML tetikleyicilerinde kullanılır. Karmaşık görünümde herhangi bir DML olayının gerçekleşeceği zaman kullanılır.
3 temel tablodan bir görünümün oluşturulduğu bir örneği düşünün. Bu view üzerinden herhangi bir DML olayı yayınlandığında veriler 3 farklı tablodan alındığı için bu geçersiz hale gelecektir. Yani bu INSTEAD OF tetikleyicisi kullanılır. INSTEAD OF tetikleyicisi, verilen olayın görünümünü değiştirmek yerine doğrudan temel tabloları değiştirmek için kullanılır.
Örnek 1:Bu örnekte iki temel tablodan karmaşık bir görünüm oluşturacağız.
- Tablo_1 emp tablosudur ve
- Tablo_2 departman tablosudur.
Daha sonra INSTEAD OF tetikleyicisinin bu karmaşık görünümde konum ayrıntısı ifadesini UPDATE'i yayınlamak için nasıl kullanıldığını göreceğiz. Ayrıca :NEW ve :OLD'un tetikleyicilerde nasıl yararlı olduğunu da göreceğiz.
- Adım 1: Uygun sütunlarla 'emp' ve 'dept' tablosunu oluşturma
- Adım 2: Tabloyu örnek değerlerle doldurma
- Adım 3: Yukarıda oluşturulan tablo için görünüm oluşturma
- 4. Adım: Yerine tetikleyiciden önceki görünümün güncellenmesi
- Adım 5: Yerine tetikleyicinin oluşturulması
- Adım 6: Tetikleyici yerine görünümün güncellenmesi
) 1 Adım Uygun sütunlarla 'emp' ve 'dept' tablosu oluşturma
CREATE TABLE emp( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager VARCHAR2(50), dept_no NUMBER); / CREATE TABLE dept( Dept_no NUMBER, Dept_name VARCHAR2(50), LOCATION VARCHAR2(50)); /
Kod Açıklama
- Kod satırı 1-7: Tablo 'emp' oluşturma.
- Kod satırı 8-12: Tablo 'departman' oluşturma.
Çıktı
Tablo Oluşturuldu
) 2 Adım Artık tabloyu oluşturduğumuza göre, bu tabloyu yukarıdaki tablolar için örnek değerlerle ve Görünüm Oluşturma ile dolduracağız.
BEGIN INSERT INTO DEPT VALUES(10,‘HR’,‘USA’); INSERT INTO DEPT VALUES(20,'SALES','UK’); INSERT INTO DEPT VALUES(30,‘FINANCIAL',‘JAPAN'); COMMIT; END; / BEGIN INSERT INTO EMP VALUES(1000,'XXX5,15000,'AAA',30); INSERT INTO EMP VALUES(1001,‘YYY5,18000,‘AAA’,20) ; INSERT INTO EMP VALUES(1002,‘ZZZ5,20000,‘AAA',10); COMMIT; END; /
Kod Açıklama
- Kod satırı 13-19: 'dept' tablosuna veri ekleme.
- Kod satırı 20-26: Verileri 'emp' tablosuna ekleme.
Çıktı
PL/SQL prosedürü tamamlandı
) 3 Adım Yukarıda oluşturulan tablo için bir görünüm oluşturma.
CREATE VIEW guru99_emp_view( Employee_name:dept_name,location) AS SELECT emp.emp_name,dept.dept_name,dept.location FROM emp,dept WHERE emp.dept_no=dept.dept_no; /
SELECT * FROM guru99_emp_view;
Kod Açıklama
- Kod satırı 27-32: 'Guru99_emp_view' görünümünün oluşturulması.
- Kod satırı 33: guru99_emp_view sorgulanıyor.
Çıktı
Oluşturulanları görüntüle
ÇALIŞAN ADI | DEPT_NAME | KONUM |
---|---|---|
ZZZ | HR | ABD |
YYY | SATIŞ | UK |
XXX | FİNANSAL | JAPONYA |
) 4 Adım Tetikleyici yerine önceki görünümün güncellenmesi.
BEGIN UPDATE guru99_emp_view SET location='FRANCE' WHERE employee_name=:'XXX’; COMMIT; END; /
Kod Açıklama
- Kod satırı 34-38: “XXX”in konumunu 'FRANSA' olarak güncelleyin. İstisnayı gündeme getirdi çünkü DML ifadeleri karmaşık görünümde izin verilmez.
Çıktı
ORA-01779: anahtarı korunmayan bir tabloya eşlenen bir sütun değiştirilemez
ORA-06512: 2. satırda
) 5 AdımBir önceki adımda görünümü güncellerken hatayla karşılaşmamak için bu adımda “trigger yerine” kullanacağız.
CREATE TRIGGER guru99_view_modify_trg INSTEAD OF UPDATE ON guru99_emp_view FOR EACH ROW BEGIN UPDATE dept SET location=:new.location WHERE dept_name=:old.dept_name; END; /
Kod Açıklama
- Kod satırı 39: SATIR düzeyinde 'guru99_emp_view' görünümünde 'UPDATE' olayı için INSTEAD OF tetikleyicisinin oluşturulması. 'Dept' temel tablosundaki konumu güncellemek için update ifadesini içerir.
- Kod satırı 44: Güncelleme ifadesi, güncellemeden önceki ve sonraki sütunların değerini bulmak için ':YENİ' ve ':ESKİ'yi kullanır.
Çıktı
Tetikleyici Oluşturuldu
) 6 Adım Yerine tetikleyiciden sonra görünümün güncellenmesi. Artık hata gelmeyecek çünkü "yerine tetikleyici" bu karmaşık görünümün güncelleme işlemini yönetecek. Ve kod yürütüldüğünde çalışan XXX'in konumu "Japonya"dan "Fransa"ya güncellenecek.
BEGIN UPDATE guru99_emp_view SET location='FRANCE' WHERE employee_name='XXX'; COMMIT; END; /
SELECT * FROM guru99_emp_view;
Kod Açıklaması:
- Kod satırı 49-53: “XXX”in konumu 'FRANSA' olarak güncellendi. Başarılı çünkü 'INSTEAD OF' tetikleyicisi görünümdeki gerçek güncelleme ifadesini durdurdu ve temel tablo güncellemesini gerçekleştirdi.
- Kod satırı 55: Güncellenen kaydın doğrulanması.
Çıktı:
PL/SQL prosedürü başarıyla tamamlandı
ÇALIŞAN ADI | DEPT_NAME | KONUM |
---|---|---|
ZZZ | HR | ABD |
YYY | SATIŞ | UK |
XXX | FİNANSAL | FRANSA |
Bileşik Tetikleyici
Bileşik tetikleyici, tek tetikleyici gövdesindeki dört zamanlama noktasının her biri için eylemleri belirtmenize olanak tanıyan bir tetikleyicidir. Desteklediği dört farklı zamanlama noktası aşağıdaki gibidir.
- AÇIKLAMADAN ÖNCE – seviye
- SIRADAN ÖNCE – seviye
- SATIRDAN SONRA – seviye
- AÇIKLAMADAN SONRA – seviye
Farklı zamanlamalara ait eylemleri aynı tetikleyicide birleştirme olanağı sağlar.
CREATE [ OR REPLACE ] TRIGGER <trigger_name> FOR [INSERT | UPDATE | DELET.......] ON <name of underlying object> <Declarative part> BEFORE STATEMENT IS BEGIN <Execution part>; END BEFORE STATEMENT; BEFORE EACH ROW IS BEGIN <Execution part>; END EACH ROW; AFTER EACH ROW IS BEGIN <Execution part>; END AFTER EACH ROW; AFTER STATEMENT IS BEGIN <Execution part>; END AFTER STATEMENT; END;
Sözdizimi Açıklaması:
- Yukarıdaki sözdizimi 'BİLEŞİK' tetikleyicisinin oluşturulmasını gösterir.
- Bildirim bölümü, tetikleyici gövdesindeki tüm yürütme bloğu için ortaktır.
- Bu 4 zamanlama bloğu herhangi bir sırada olabilir. Bu 4 zamanlama bloğunun hepsine sahip olmak zorunlu değildir. Yalnızca gerekli zamanlamalar için BİLEŞİK tetikleyici oluşturabiliriz.
Örnek 1: Bu örnekte, maaş sütununu varsayılan değer olan 5000 ile otomatik olarak doldurmak için bir tetikleyici oluşturacağız.
CREATE TRIGGER emp_trig FOR INSERT ON emp COMPOUND TRIGGER BEFORE EACH ROW IS BEGIN :new.salary:=5000; END BEFORE EACH ROW; END emp_trig; /
BEGIN INSERT INTO EMP VALUES(1004,‘CCC’,15000,‘AAA’,30); COMMIT; END; /
SELECT * FROM emp WHERE emp_no=1004;
Kod Açıklaması:
- Kod satırı 2-10: Bileşik tetikleyicinin oluşturulması. Maaşın varsayılan değeri 5000 ile doldurulması için ÖNCE SATIR düzeyi zamanlaması için oluşturulmuştur. Bu, kaydı tabloya eklemeden önce maaşı varsayılan değer '5000' olarak değiştirecektir.
- Kod satırı 11-14: Kaydı 'emp' tablosuna ekleyin.
- Kod satırı 16: Eklenen kaydın doğrulanması.
Çıktı:
Tetikleyici oluşturuldu
PL/SQL prosedürü başarıyla tamamlandı.
EMP_NAME | EMP_NO | MAAŞ | MÜDÜRÜ | DEPT_NO |
---|---|---|---|---|
CCC | 1004 | 5000 | AAA | 30 |
Tetikleyicileri Etkinleştirme ve Devre Dışı Bırakma
Tetikleyiciler etkinleştirilebilir veya devre dışı bırakılabilir. Tetikleyiciyi etkinleştirmek veya devre dışı bırakmak için, onu devre dışı bırakan veya etkinleştiren tetikleyiciye ALTER (DDL) ifadesinin verilmesi gerekir.
Aşağıda tetikleyicileri etkinleştirme/devre dışı bırakma sözdizimi verilmiştir.
ALTER TRIGGER <trigger_name> [ENABLE|DISABLE]; ALTER TABLE <table_name> [ENABLE|DISABLE] ALL TRIGGERS;
Sözdizimi Açıklaması:
- İlk sözdizimi, tek tetikleyicinin nasıl etkinleştirileceğini/devre dışı bırakılacağını gösterir.
- İkinci ifade, belirli bir tablodaki tüm tetikleyicilerin nasıl etkinleştirileceğini/devre dışı bırakılacağını gösterir.
ÖZET
Bu bölümde PL/SQL tetikleyicilerini ve avantajlarını öğrendik. Ayrıca farklı sınıflandırmaları da öğrendik ve tetikleyici yerine BİLEŞİK tetikleyiciyi tartıştık.