Sunum yükleniyor. Lütfen bekleyiniz

Sunum yükleniyor. Lütfen bekleyiniz

Veri Tabanı Yönetim Sistemleri 2 Ders 7 Paket ve Tetikleyiciler

Benzer bir sunumlar


... konulu sunumlar: "Veri Tabanı Yönetim Sistemleri 2 Ders 7 Paket ve Tetikleyiciler"— Sunum transkripti:

1 Veri Tabanı Yönetim Sistemleri 2 Ders 7 Paket ve Tetikleyiciler
Yrd. Doç. Dr. Altan MESUT Trakya Üniversitesi Bilgisayar Mühendisliği Bölümü

2 Paket (Package) Birbiriyle ilişkili olan prosedürlerin, fonksiyonların, değişkenlerin ve diğer yapıların bir bütün haline getirildiği ve veritabanında saklandığı yapıdır. Bir global değişkenin tanımlanıp paket içindeki herhangi bir prosedürde kullanılabilmesi gibi ekstra özellikler sağlar. Ayrıca paketler bir bütün halinde bir kerede parse edilip, derlenip, belleğe yüklendiği için performans artışı da sağlar. Paketlerde tanımlama (specification) ve gövde (body) olmak üzere iki kısım bulunur. Gerektiğinde tanımlama kısmına dokunulmadan sadece gövde kısmı tekrar derlenebilir. Paketi kullanan ve sadece tanımlama kısmını görebilen (encapsulation) uygulamaların tekrar derlenmesine gerek yoktur. Paketler hakkında detaylı bilgi için: Database Programming with PL/SQL, Section 10

3 Paket Örneği CREATE PACKAGE emp_actions AS -- package specification PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...); PROCEDURE fire_employee (emp_id NUMBER); END emp_actions; CREATE PACKAGE BODY emp_actions AS -- package body PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...) IS BEGIN INSERT INTO emp VALUES (empno, ename, ...); END hire_employee; PROCEDURE fire_employee (emp_id NUMBER) IS DELETE FROM emp WHERE empno = emp_id; END fire_employee;

4 Public & Private Paketin tanım kısmında yapılan değişken, prosedür veya fonksiyon tanımları Public türündedir yani bu yapılar paketin dışından da çağrılabilir (EXECUTE yetkisi verilmiş kullanıcılar tarafından). Private bileşenler sadece paketin gövdesinde kullanılabilir ve aynı paket içinden çağrılabilir. İstenirse Public sözcüğü ile gövde kısmında da global değişken yaratılabilir.

5 Aşırı Yükleme (Overloading)
NYP dersinden hatırlayacağınız aşırı yükleme kavramı PL/SQL’de de vardır. Yani aynı paket içinde aynı isimde fonksiyonların veya prosedürlerin kullanılabilmesi mümkündür. Parametrelerin sayısının veya veri türlerinin farklı olması gerektiğini biliyoruz. Burada dikkat edilecek olan NUMBER ile INTEGER, VARCHAR2 ile CHAR aynı tür olarak kabul edilir. CREATE OR REPLACE PACKAGE emp_pkg IS PROCEDURE find_emp -- 1 (p_employee_id IN NUMBER, p_last_name OUT VARCHAR2); PROCEDURE find_emp -- 2 (p_job_id IN VARCHAR2, p_last_name OUT VARCHAR2); PROCEDURE find_emp -- 3 (p_hiredate IN DATE, p_last_name OUT VARCHAR2); END emp_pkg;

6 STANDARD Paketi Oracle’da tanımlı olan TO_CHAR, TO_DATE, UPPER, … gibi tüm hazır fonksiyonlar STANDARD paketinde bulunur. Eğer Oracle STANDARD paketinde bulunan bir fonksiyon ile aynı isimde bir fonksiyon yaratırsanız, kendi fonksiyonunuzu kullanmak için öncesinde kendi şemanızın ismini vermeniz gerekir: BEGIN v_deger := şema_adı.UPPER(parametre); END;

7 Forward Declaration C dilinde olduğu gibi paket gövdesinde yazdığınız bir belirleyicinin (değişken, prosedür veya fonksiyon ismi) kullanılabilmesi için önceden tanımlanmış olması gerekir.

8 Tetikleyici (Trigger)
Sisteme bir kullanıcının bağlanması, bir tablo yaratılması veya tanımında değişiklik yapılması, tablo veya görüntü üzerinde bir DML ifadesinin değişiklik yapması gibi bir olay ile tetiklenen ve veritabanında saklanan PL/SQL bloğudur. Otomatik olarak log ve izleme kayıtları yaratma, karmaşık veri bütünlüğü ve güvenlik kuralları koyma, istenmeyen DML işlemlerini engelleme ve bazı verilerdeki değişimlerin başka verileri de değiştirmesini sağlama gibi işler için kullanılırlar. NOT: Foreign Key ile basitçe yapabileceğiniz veri bütünlüğü kısıtlaması gibi işler için tetikleyici oluşturmayın Detaylı bilgi için: Database Programming with PL/SQL, Section 13

9 DML Tetikleyici Veri tabanında bir DML işlemi gerçekleştiğinde otomatik olarak verilen PL/SQL bloğunu çalıştıran tetikleyici türüdür. Bir olaydan (insert, delete ya da update ifadelerin belirtilen tabloda oluşması) ve bir hareketten (ilgili prosedür) oluşur. Örneğin; personel tablosundan bir kaydın silinmesi olayı gerçekleştiğinde, eski_personel tablosuna personelin numarasını ve işten ayrılma tarihini belirtmek için o anki tarihi kaydeden bir prosedür yazılması ile bir tetikleyici oluşturulabilir.

10 DML Tetikleyici Yaratma
CREATE [or REPLACE] TRIGGER Trigger Adı Tetikleme Zamanı Olay1 [OR Olay2 OR Olay3] ON Tablo veya Görüntü Adı [FOR EACH ROW] [WHEN Koşul] BEGIN PL/SQL Bloğu END; Tetikleme Zamanı: BEFORE / AFTER: DML ifadesinden önce / sonra tetiklenmesi INSTEAD OF: DML’in yerine bloğu çalıştırır, DML gerçekleşmez Olay: INSERT, DELETE veya UPDATE [of Sütun Adı] olabilir FOR EACH ROW: Etkilenen her satır için bloğu tekrar çalıştırır WHEN: Belirli bir koşul oluştuğunda bloğu çalıştırır

11 DML İfade Bazlı Tetikleyici Örneği
CREATE TRIGGER HaftaSonundaEngelleme BEFORE INSERT OR DELETE OR UPDATE ON Personel BEGIN IF TO_CHAR(SYSDATE,'DY') IN ('SAT','SUN') THEN RAISE_APPLICATION_ERROR(-20500, 'Personel tablosunda sadece çalışma' || ' saatlerinde değişiklik yapılabilir'); END IF; END; DML işleminden birçok kayıt etkilense de, hiçbir kayıt etkilenmese de ifade bazlı tetikleyici bloğu sadece bir defa çalışır. Eğer farklı mesajlar görüntülenmesini isterseniz "if inserting then … elsif deleting then … elsif updating then …" kullanılabilir.

12 DML Satır Bazlı Tetikleyici Örneği (1)
CREATE TRIGGER log_emps AFTER UPDATE OF sal ON emp FOR EACH ROW BEGIN INSERT INTO log_emp_table (who, when, which_employee, old_sal, new_sal) VALUES (USER, SYSDATE, :OLD.empno, :OLD.sal, :NEW.sal); END; Etkilenen her kayıt için aşağıdaki blok tekrar çalışacak (satır bazlı tetikleyici) Bu tetikleyici Emp tablosunda maaşı değişen her kayıt için log_emp_table tablosuna yeni kayıt (kim değiştirdi, ne zaman değişti, kimin maaşı, eski maaş, yeni maaş) ekler.

13 DML Satır Bazlı Tetikleyici Örneği (2)
Ledger tablosuna ekleme yapılmadan önce yeni değerler, güncelleme yapılmadan önce ise eski değerler LedgerAudit tablosuna eklenir.

14 DML Satır Bazlı Tetikleyici Örneği (3)
CREATE TRIGGER emp_dept_fk_trg BEFORE UPDATE OF deptno ON emp FOR EACH ROW DECLARE v_dept_no dept.deptno%TYPE; BEGIN SELECT deptno INTO v_dept_no FROM dept WHERE deptno = :NEW.deptno; EXCEPTION WHEN NO_DATA_FOUND THEN INSERT INTO dept VALUES(:NEW.deptno, NULL, NULL); END; Bu tetikleyici EMP tablosundaki bir personelin bölümü değiştirildiğinde, eğer o bölüm numarası DEPT tablosunda yoksa ekler (bölüm adı ve yeri bilgileri NULL olacak şekilde)

15 INSTEAD OF Tetikleyici
INSTEAD OF tetikleyiciler sadece görüntüler üzerinde tanımlanabilir ve satır bazlı çalışırlar. Genel olarak üzerinde DML işlemi yapamadığımız karmaşık görüntüler üzerinde bu işlemlerin yapılamasını sağlamak için kullanılırlar. Karmaşık görüntüleri işlerken örneğini verdiğimiz emp_view görüntüsü iki tabloyu kapsayan bir sorgu içerdiği için üzerinde DML işlemi yapamayacağımızı görmüştük: CREATE VIEW emp_view AS SELECT empno, ename, sal, loc FROM emp, dept WHERE emp.deptno = dept.deptno AND dept.deptno = 10;

16 INSTEAD OF Tetikleyici Örneği
Aşağıdaki INSTEAD OF tetikleyici sayesinde emp_view görüntüsü üzerinde ekleme işlemi yapılması sağlanabilir. CREATE TRIGGER new_emp_dept INSTEAD OF INSERT ON emp_view BEGIN INSERT INTO emp(empno, ename, sal, deptno) VALUES(:NEW.empno,:NEW.ename,:NEW.sal,10); END; Görüntü sadece 10 numaralı bölüme ait kayıtları gösterdiği için emp tablosuna yeni kaydı eklerken bölümünü 10 olarak belirledik

17 DML Tetikleyiciler Hakkında Notlar
Eski ve yeni değerleri ifade eden :OLD ve :NEW sadece satır bazlı tetikleyiciler ile kullanılır. Ekleme işleminde sadece yeni değer, silme işleminde sadece eski değer, güncelleme işleminde ise ikisi birden vardır. :OLD ve :NEW yerine :eski ve :yeni gibi farklı isimler kullanılması istenirse FOR EACH ROW öncesinde aşağıdaki gibi bir ifade yazılır: REFERENCING OLD AS eski NEW AS yeni Bir DML ifadesi tarafından değiştirilmekte olan bir tablo üzerinde satır tetikleyiciler sorgu veya değişiklik yapamaz (ifade tetikleyiciler yapabilir). Derleme sırasında hata vermese de tetiklendiği anda " tablo … değişiyor, tetikleyici/fonksiyon onu göremez" hatasını verir. Hatanın İngilizcesi "table … is mutating, trigger/function may not see it" olduğu için "Mutating Table" hatası olarak bilinir.

18 Bileşik Tetikleyici (Compound Trigger)
Birleşik tetikleyici içinde birden çok tetikleme zamanı bulunabilir. Bu zamanlar tetiklenme sırasına göre: Before Statement, Before Each Row, After Each Row ve After Statement şeklindedir. Bu zamanların hepsi tanımlanmak zorunda değildir. Sadece kullanmak istediğiniz kadarını yazabilirsiniz. Az önce değindiğimiz "Mutating Table" hatasını engellemek için (sonraki slaytta yer alan örnek bunu sağlar) veya DML’den etkilenen satırları topluca işlemek üzere bir araya getirmek için kullanılır.

19 Bileşik Tetikleyici Örneği
CREATE TRIGGER MutatingEngellemeTrigger FOR UPDATE OF empno ON emp COMPOUND TRIGGER v_empno NUMBER; AFTER EACH ROW IS BEGIN v_empno := :NEW.empno; END AFTER EACH ROW; AFTER STATEMENT IS UPDATE emp SET deptno = FLOOR(empno / 1000) * 10 WHERE empno = v_empno; END AFTER STATEMENT; END; Bileşik tetikleyiciler çok zamanlı oldukları için tanımlarken BEFORE/AFTER yerine FOR yazılır. Bu örnekte sadece AFTER EACH ROW ve AFTER STATEMENT kullanılmıştır. Satır bazlı kısımda hangi personelin update edildiğini v_empno değişkenine atadık ve aynı değişkeni ifade bazlı kısımda kullanabildik. SCOTT.EMP tablosunda empno alanı güncellenirken tetiklenen bu trigger, personelin 4 haneli numarası ile bulunduğu departmanın iki haneli numarasının ilk rakamlarının denk olmasını sağlar (örn: empno = 3999 ise deptno = 30). Bunu sağlamak için verilen empno 3999 ise onu 1000’e böler ve aşağı yuvarlar (3). Bulduğu değeri 10 ile çarparak yeni deptno’yu bulur (30) ve günceller (4000 olsaydı 40 bulacaktı).

20 DDL Tetikleyici DDL ifadelerinden biri yürütüldüğünde tetiklenen türdür. Tetikleme Zamanı: BEFORE, AFTER veya INSTEAD OF olabilir. Olay: CREATE, DROP veya ALTER olabilir. ON SCHEMA sadece kendi şemanızdaki, ON DATABASE ise tüm şemalardaki nesneler üzerindeki DDL işlemlerinde tetiklenir. CREATE [or REPLACE] TRIGGER Trigger Adı Tetikleme Zamanı Olay1 [OR Olay2 OR Olay3] ON {DATABASE|SCHEMA} BEGIN PL/SQL Bloğu END;

21 DDL Tetikleyici Örnekleri
CREATE TRIGGER log_create_trigg AFTER CREATE ON SCHEMA BEGIN INSERT INTO log_table VALUES (USER, SYSDATE); END; Bir veritabanı nesnesi yaratıldıktan sonra log tablosuna bilgi ekler CREATE TRIGGER prevent_drop_trigg BEFORE DROP ON SCHEMA BEGIN RAISE_APPLICATION_ERROR (-20203, 'Attempted drop – failed'); END; Bir veritabanı nesnesi silinmek istendiğinde engel olur

22 Veritabanı Olay Tetikleyicileri
Bir kullanıcının veritabanına bağlanması veya çıkış yapması, veritabanının açılması veya kapanması, belirli bir exception çağrılması gibi durumlarda da tetiklenen türdür. Yaratılması DDL Tetikleyici ile benzerdir. ON SCHEMA yazılması sadece kendi oturumunuzdaki olaylarda, ON DATABASE yazılması ise tüm oturumlardaki olaylarda tetiklenmesini sağlar.

23 LOGON ve LOGOFF Tetikleyici Örnekleri
CREATE TRIGGER logon_trigg AFTER LOGON ON DATABASE BEGIN INSERT INTO log_table(user_id,log_date,action) VALUES (USER, SYSDATE, 'Bağlandı'); END; CREATE TRIGGER logoff_trigg BEFORE LOGOFF ON SCHEMA VALUES (USER, SYSDATE, 'Çıkış Yaptı'); Sisteme bağlanan her kişi için ID’si, bağlanma tarihi ve ilgili mesajı log tablosuna kaydeder Sistemden çıkan her kişi için ID’si, bağlanma tarihi ve ilgili mesajı log tablosuna kaydeder

24 SERVERERROR Tetikleyici Örneği
CREATE TRIGGER servererror_trig AFTER SERVERERROR ON SCHEMA BEGIN IF (IS_SERVERERROR (942)) THEN INSERT INTO error_log_table ... END IF; END;

25 Tetikleyicilerin Durumunu Değiştirme
Tetikleyiciyi devre dışı bırakmak için DISABLE, tekrar aktif hale getirmek için ENABLE kullanımı: ALTER TRIGGER trigger_adı DISABLE | ENABLE; Bir tabloya ait tüm tetikleyicilerin aynı anda devre dışı bırakılması: ALTER TABLE tablo_adı DISABLE ALL TRIGGERS; Tetikleyicinin tekrar derlenmesi: ALTER TRIGGER trigger_adı COMPILE;

26 Tetikleyiciler Hakkında Notlar
Tetikleyici yaratabilmek için sadece CREATE TRIGGER sistem yetkisine sahip olmak yeterli değildir. Tetikleyicinin ilişkili olduğu tablo üzerinde ALTER yetkisine de sahip olunmalıdır. Tetikleyici bloğunda yapılan işlemin gerektirdiği tüm yetkilere de sahip olunmalıdır. Yaratılan tetikleyiciler hakkında detaylı bilgi için USER_TRIGGERS veri sözlüğü görüntüsü kullanılabilir. Tetikleyici içinde COMMIT veya ROLLBACK yapılamaz (prosedürlerde yapılabiliyordu) CHECK constraint ile kolaylıkla sağlanabilecek maaşın 1000’den fazla olması gibi bir kısıtlama için tetikleyici kullanılırsa daha yavaş çalışır. Fakat bir personelin maaşının azaltılamamasını sağlamak için tetikleyici gerekir

27 Personelin maaşının eski maaşından ve 1000’den az olamamasını sağlayan tetikleyici
CREATE OR REPLACE TRIGGER check_salary BEFORE UPDATE OF salary ON employees FOR EACH ROW WHEN (:NEW.salary < :OLD.salary OR :NEW.salary < 1000) BEGIN RAISE_APPLICATION_ERROR (-20508, 'Maaşı azaltamazsınız'); END;

28 Personelin daha önce yaptığı bir göreve tekrar atanamamasını sağlayan tetikleyici
CREATE OR REPLACE TRIGGER check_sal_trigg BEFORE UPDATE OF job_id ON employees FOR EACH ROW DECLARE v_job_count INTEGER; BEGIN SELECT COUNT(*) INTO v_job_count FROM job_history WHERE employee_id = :OLD.employee_id AND job_id = :NEW.job_id; IF v_job_count > 0 THEN RAISE_APPLICATION_ERROR (-20201,'Bu kişi bu görevi daha önce yapmıştı'); END IF; END;

29 Crossedition Trigger Daha önce gördüğümüz Editioning View gibi, uygulamanın veritabanındaki değişiklikten etkilenmemesi amacıyla kullanılan tetikleyici türüdür. Diyelim ki adı telno olan ve veri türü number olan bir alanın veri türünü varchar2 olarak değiştirmek istediniz. Bunu UPDATE Personel SET telno_yeni = to_char(telno) yazarak ve uygulamanızın yeni sürümünde telno_yeni alanını kullanarak yapabilirsiniz ama update işlemi tablodaki tüm kayıtları kilitleyecektir. Eğer tablodaki kayıt sayısı çoksa işin bitmesi ve kilidin kaldırılması zaman alacaktır. Mevcut uygulama Personel tablosunu değil de bu tablonun tüm satırlarını içeren bir editioning view* kullanarak çalışıyorsa, tabloya ekleyeceğiniz telno_yeni alanı uygulamayı etkilemeyecektir. * Editioning View WHERE kriteri içermediği için tüm satırları kapsar ama tüm sütunları kapsamayabilir

30 Uygulamanın yeni sürümünde eskisi ile aynı isimde olan yeni edition altındaki editioning view, telno_yeni alanını telno takma adı ile içerirse, uygulama telno olarak aslında varchar2 türündeki yeni alanı kullanacaktır. Crossediton tetikleyici sadece bir edition için tetiklenen bir türüdür ve amacı uygulamanın yeni sürüme geçiş aşamasında edition’lar arası tutarlılığı sağlamaktır. Eski edition’da :NEW.telno_yeni := TO_CHAR(:NEW.telno); işlemini yapan bir tetikleyici yaratırsanız ve UPDATE Personel SET telno=telno; ifadesi ile bunu tüm tablo için tetiklerseniz yine tüm tabloyu kilitlemiş olursunuz. Fakat DBMS_PARALLEL_EXECUTE paketini kullanarak bu tetikleyicinin işlemi 1000 parçaya bölerek yapmasını, böylece tüm tablo yerine belirli bir zamanda sadece binde birini kilitlemesini sağlayabilirsiniz. Tüm işlemler bittiğinde number türündeki eski alanı silebilirsiniz. Böylece yeni sürüme geçiş süresini kısaltarak, güncelleme işini kısa süreli bir kesinti ile halledebilirsiniz.


"Veri Tabanı Yönetim Sistemleri 2 Ders 7 Paket ve Tetikleyiciler" indir ppt

Benzer bir sunumlar


Google Reklamları