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
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
PostgreSQL Error Messages
PostgreSQL Control Structures