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 :

  1. Sistem Tanımlı Exceptionlar(System Defined Exceptions)
  2. 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

Loading