PostgreSQL (pl/pgsql) - Exception Get Stacked
4 min read

PostgreSQL (pl/pgsql) - Exception Get Stacked

PostgreSQL (pl/pgsql) - Exception Get Stacked

Merhaba,

bu yazımda sizler ile birlikte PostgreSQL veri tabanında pl/pgsql ile bir fonksiyonu oluşturduğumuzda hata ile karşılaştığımızda veya hatayı yakalayıp bilgi almak istediğimizde hangi işlemleri yapmamız gerektiğini anlatmaya çalışacağım.

Fonksiyonu Tanıyalım

Aşağıda vermiş olduğum fonksiyon üzerinden işlem yapacağım.

CREATE FUNCTION "public"."ExceptionTEst"()
	RETURNS "pg_catalog"."text" AS $BODY$BEGIN
	-- Routine body goes here...

	RETURN 'ExceptionTest';
END$BODY$
	LANGUAGE plpgsql

ExceptionTest adında text değer dönderen bir fonksiyon diyebiliriz. Fonksiyon kodlarımız ise;

CREATE OR REPLACE FUNCTION "public"."ExceptionTEst"()
  RETURNS "pg_catalog"."text" AS $BODY$BEGIN
declare
 dec_metin text;
begin
 dec_metin := 'halilhanbadem.dev';
 RETURN dec_metin;
end;

	
END$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100

Burada halilhanbadem.dev adında bir text değişkeni oluşturduk ve dönüş olarak yine bu değişken değerini verdik. Burada fonksiyonun önemi yok. Önemli olan bir hata oluşturup bu hatayı nasıl detaylı şekilde aktaracağımız. Hatalı kodumuz;

CREATE OR REPLACE FUNCTION "public"."ExceptionTEst"()
  RETURNS "pg_catalog"."text" AS $BODY$BEGIN
declare
 dec_metin text;
begin
 dec_metin := 'halilhanbadem.dev';
 RETURN cast(dec_metin as integer);
end;

	
END$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100

Burada değeri integer değere dönüştürüp, return etmeye çalışacağız fakat; dec_metin içerisinde text değer olduğu için bunu gerçekleştirmeyecek. halilhanbadem.dev yerine 1,2,3 gibi değerler olsaydı sorun yaşamayacaktık. Buradan çıkan exception ile yazımızın konusuna dönelim ama öncesinde verdiği hata;

HATA:  integer tipi için geçersiz giriş sözdizimi: "halilhanbadem.dev"
CONTEXT:  "ExceptionTEst"() PL/pgSQL fonksiyonu, 6. satır, RETURN içinde

Exception

Üst taraf da istisnayı nasıl oluşturacağımızı çözdük. Şimdi sıra bu istisnayı yönetebilmekte. Önce yorumlu kodu altına ise açıklamalarını yapacağım.

CREATE OR REPLACE FUNCTION "public"."ExceptionTEst"()
  RETURNS "pg_catalog"."text" AS $BODY$BEGIN
declare
 dec_metin text; ---bu kısımda değerimizi set ettiğimiz değişken var.
 hata text; ---bu kısımda hatamızı set edeceğimiz değişkenimiz mevcut.
begin --- fonksiyon başlangıcı
 dec_metin := 'halilhanbadem.dev'; ---dec_metin set ediliyor...
 begin ---exception begin...end aralığı
	RETURN cast(dec_metin as integer); ---değerimizi integer tipine dönüştürmeye çalışıyoruz ve sonuç olarak döndürüyoruz.
  EXCEPTION WHEN OTHERS THEN ---exception başlangıcımız. when others tüm exceptionlar için kullanılıyor. Herhangi bir istisna dahil edilebilir.
 begin ---exception başlangıcı
  GET STACKED DIAGNOSTICS hata := message_text; ---get stacked ile ilgili hatanın mesajı "hata" değişkenine set ediliyor.
  return hata; ---hata aralığında olduğu için sonuç olarak hata dönüş yapıyor.
 end;
 end;
end;	
END$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100

Yorum olarak yazdım fakat karışık gelebilir hızlıca özet geçeyim. İlk olarak declare...begin aralığına değişkenlerimizin tanımını yapıyoruz. Bunlar text türünde iki adet değişken. Sonrasında ise begin...end aralığında fonksiyonumuz başlıyor. Fonksiyonumuzda ilk olarak dec_metin değişkenimize yazımızı set ediyoruz. Set edildikten sonra begin...exception...end yapısı ile istisna kontrollü bir kod bloğuna girmiş bulunmaktayız.  

return cast(dec_metin as integer)

 yukarıda bulunan kod ile dönüş yaparken integer tipini dönüştürüp işlem yapmasını sağlıyoruz. sonrasında;

EXCEPTION WHEN OTHERS THEN

satırı ile herhangi bir istisna durumunda hemen kodun altında bulunan begin...end bloğuna girmesini istiyoruz.

 GET STACKED DIAGNOSTICS hata := message_text;
 RETURN hata; 

get stacked diagnostics ile herhangi bir istina bloğunda istediğiniz değerleri (hata açıklaması, hata kodu vb.) alıp set edebilirsiniz. İşlem sonrasında dönüş hata mesajı olarak set edilmiştir.

Sonuca Bakalım

istisna ile dönen değer
sayısal değer girildiğinde dönen değer

Bu şekilde hedefimize ulaşmış oluyoruz. Kafa karışıklığına sebep olmaması için;

Biz text tipinde dönüş yapan bir fonksiyon oluşturduk fakat sayısal değer girince cast fonksiyonu ile integer tipini dönüştürüp return ettik. Bu durumda fonksiyonun tipi mi değişiyor?

Hayır. Bu kısımda dönen veya oluşan değerler istemci tarafında yine text değerinde olacaktır. Bir istemci ile test edebilirsiniz. Dönen değer tipi kullandığınız dilin string tipine eşit olacaktır.

Dökümanlar:

PostgreSQL Exception
Errors and Messages
Control Structures

İyi çalışmalar dilerim.