Exception kelimesinin Türkçe karşılığı istisna demektir ve PL/SQL ‘de hataları yakalamak için kullanılan yapıya bu ad verilir. Exception blokları sayesinde kod içerisinde karşılaşılması öngörülen hatalar yakalanıp gerekli işlemler yapılabilir.
Eğer programımızda hata kontrolü yoksa programın çalışması durur ve programın kontrolü işletim sistemine döner. Hata kontrolü varsa da program hatalara rağmen devam edebilir.
Exception iki türlü tanımlanabilir :
- Sistem Tanımlı Exceptionlar(System Defined Exceptions)
- Kullanıcı Tanımlı Exceptionlar(User Defined Exceptions)
Kullanıcı Tanımlı Exceptionlar(User Defined Exceptions)
Bir uygulama yazıyorsunuz ve bu uygulamaya özel bazı hatalarınız oluşuyor ve bunları yakalamak ,ekrana bilgi vermek ya da loglamak istiyorsunuz. Bu gibi durumlarda PL/SQL sadece sistem tanımlı olan exceptionları değil kendi tanımladığınız hatalarınızı da yakalama şansı veriyor.
PL/SQL de hata tanımlaması yaparken aşağıdaki sintaksisi kullanıyoruz ;
DECLARE my-exception EXCEPTION;
Aşagıdaki örnekte bir exception tanımlıyoruz id’yi sıfır’ın altında girersek ex_invalid_id exceptionu çalışacak.Başka bir hata durumunda ise tanımlı gelen exceptionlardan birisi çalışacak.
NOT : Exception’ı hata olarak yakalaması için RAISE ifadesini kullandık. Raise’in karşılığı ‘uyandırmak’ olarak düşünülebilir ve burada ‘git ve oluşturduğum hatayı uyandır cevabını versin’ diyorsunuz
DECLARE v_id hr.employees.employee_id%type := &cc_id; v_name hr.employees.first_name%type; v_surn hr.employees.last_name%type; -- exception tanimlariz ex_invalid_id EXCEPTION; BEGIN --exception sartini belirtiriz IF v_id <= 0 THEN RAISE ex_invalid_id; ELSE SELECT first_name, last_name INTO v_name, v_surn FROM hr.employees WHERE employee_id = v_id; DBMS_OUTPUT.PUT_LINE ('Name: '|| v_name); DBMS_OUTPUT.PUT_LINE ('Surname: ' || v_surn); END IF; EXCEPTION --tanimladigimiz exception ise WHEN ex_invalid_id THEN dbms_output.put_line('ID must be greater than zero!'); WHEN no_data_found THEN dbms_output.put_line('No such customer!'); WHEN others THEN dbms_output.put_line('Error!'); END; /
Sistem Tanımlı Exceptionlar(System Defined Exceptions)
PL/SQL’de yaptığımız işlemler üzerinde oluşan bazı hataları Oracle bizim için yakalıyor.Mesela bir sql işlemi yaptınız ve select çektiniz,bu select içerisinde herhangi bir data yok ise NO_DATA_FOUND exception’ı sistem tarafından tanımlanmıştır ve siz direk yakalayabilirsiniz.
DECLARE v_id NUMBER; v_name VARCHAR2(20); v_surname hr.employees.last_name%type ; BEGIN SELECT employee_id, first_name, last_name INTO v_id, v_name, v_surname FROM hr.employees WHERE employee_id=1000; dbms_output.put_line('ID : '||v_id); dbms_output.put_line('Name : '||v_name); dbms_output.put_line('Surname : '||v_surname); EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line('No such employee'); WHEN OTHERS THEN dbms_output.put_line('ERROR!'); END; /
Sistem tarafından tanımlı hatalar ne zaman PL/SQL de bir hata olursa, o zaman tetiklenirler. Oracle hatalarının hepsinin bir hata numarası vardır; ancak bu hatalar adlarıyla kontrol edilirler.
Genel olarak ortaya çıkacak hataları “OTHERS” ifadesiyle kapsayabiliriz. Hatalar ortaya çıktığında SQLCODE ve SQLERRM fonksiyonları işimize yarayabilir. SQLCODE fonksiyonu SQL hata numarasını verirken, SQLERRM ise SQL hata mesajını vermektedir.
Ayrıca diğer adı olmayan hataları işlemek için “pragma exception init” ifadesini kullanabiliriz.
DECLARE v_id NUMBER; v_name VARCHAR2(20); v_surname hr.employees.last_name%type ; BEGIN SELECT employee_id, first_name, last_name INTO v_id, v_name, v_surname FROM hr.employees WHERE employee_id=1000; dbms_output.put_line('ID : '||v_id); dbms_output.put_line('Name : '||v_name); dbms_output.put_line('Surname : '||v_surname); EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line('Alinan Hata Kodu : '||sqlcode); dbms_output.put_line('Alinan Hata Mesaji : '||sqlerrm); WHEN OTHERS THEN dbms_output.put_line('ERROR!'); END; /
Aşağıdaki hatalar hata koduna tanımlı isim verilmiş olan hatalardır.
Exception | Oracle Error | SQLCODE |
ACCESS_INTO_NULL | 06530 | -6530 |
CASE_NOT_FOUND | 06592 | -6592 |
COLLECTION_IS_NULL | 06531 | -6531 |
DUP_VAL_ON_INDEX | 00001 | -1 |
INVALID_CURSOR | 01001 | -1001 |
INVALID_NUMBER | 01722 | -1722 |
LOGIN_DENIED | 01017 | -1017 |
NO_DATA_FOUND | 01403 | +100 |
NOT_LOGGED_ON | 01012 | -1012 |
PROGRAM_ERROR | 06501 | -6501 |
ROWTYPE_MISMATCH | 06504 | -6504 |
SELF_IS_NULL | 30625 | -30625 |
STORAGE_ERROR | 06500 | -6500 |
TOO_MANY_ROWS | 01422 | -1422 |
VALUE_ERROR | 06502 | -6502 |
ZERO_DIVIDE | 01476 | 1476 |
declare v_result number; begin SELECT 100/0 INTO v_result FROM dual; exception WHEN ZERO_DIVIDE THEN dbms_output.put_line('Bolen sifira esittir - ' || sqlerrm); WHEN others THEN dbms_output.put_line('Alınan Hata : ' || sqlerrm); end; /
declare v_result varchar2(50); begin select owner into v_result from all_tables where owner = 'SYS'; exception WHEN TOO_MANY_ROWS THEN dbms_output.put_line('Birden fazla kayit gelmekte - ' || sqlerrm); WHEN others THEN dbms_output.put_line('Alınan Hata : ' || sqlerrm); end; /
CREATE TABLE test_excep ( id NUMBER, description VARCHAR2 (100), CONSTRAINT test_excep_pk PRIMARY KEY (id) ); begin insert into test_excep (id, description) values (1, 'TEST01'); commit; insert into test_excep (id, description) values (1, 'TEST01'); commit; exception when DUP_VAL_ON_INDEX then dbms_output.put_line('Alınan Hata : ' || sqlerrm); end; /
Yararlı olması Dilegiyle …
Yazar : Mustafa Bektaş Tepe
Kaynaklar;
http://www.tutorialspoint.com/plsql/plsql_basic_syntax.htm
https://developersdaily.wordpress.com
http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/
https://docs.oracle.com/cd/E11882_01/appdev.112/e40758/toc.htm
https://oracle-base.com/articles/misc/introduction-to-plsql