ProgramlamaVeritabanı Geliştiricisi

Hata işleme ve hata ayıklama prosedürlerini SQL'deki saklı prosedürlerde nasıl etkili bir şekilde uygulayabilirsiniz? Hata yakalama ve günlüğe kaydetme için hangi mekanizmalar mevcuttur? Bu yaklaşımlar farklı DBMS'lerde nasıl farklılık gösterir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Saklı prosedürlerde hataları özel yapılarla işlemek mümkündür ve gereklidir.

SQL Server'da ana mekanizmalar TRY...CATCH bloklarıdır; burada TRY içindeki tüm hatalar yakalanır ve CATCH'te detaylar kaydedilebilir. Hata detaylarını almak için ERROR_NUMBER(), ERROR_MESSAGE() gibi fonksiyonlar mevcuttur.

BEGIN TRY -- Riskli işlem UPDATE Accounts SET balance = balance - 100 WHERE id = 1; END TRY BEGIN CATCH INSERT INTO ErrorLog( ErrorTime, ErrorNumber, ErrorMessage, UserName ) VALUES ( GETDATE(), ERROR_NUMBER(), ERROR_MESSAGE(), SUSER_SNAME() ); -- Ek geri kazanım veya ROLLBACK END CATCH

Oracle'da genellikle EXCEPTION blokları kullanılır:

BEGIN UPDATE ...; EXCEPTION WHEN OTHERS THEN INSERT INTO error_log VALUES (..., SQLERRM); END;

Unutulmaması gereken noktalar:

  • CATCH, örneğin, ayrıştırma veya derleme hataları gibi tüm hataları yakalamaz; bu hatalar TRY'e girmeden işlemi geri alır.
  • Bilgileri günlüğe kaydetmek için hatalar için ayrı bir tablo bulundurmak önemlidir.
  • Mümkün olduğunca fazla bilgi günlüğe kaydedilmeli: hata metni, numarası, kullanıcı adı, işlem parametreleri.
  • Farklı DBMS'lerde sözdizimi ve olanaklar farklılık gösterir.

Tuzaklı Soru.

CATCH bloğundaki bir farklılık, hata bağlamını kaybetmeye neden olabilir mi? İç içe hata işleme nasıl gerçekleştirilir?

Cevap ve örnek: CATCH bloğunda bir hata oluşursa (örneğin, ErrorLog tablosunun erişilememesi nedeniyle), orijinal hata bağlamı kaybolur ve başarısızlık nedeni hakkında bilgi kaybolabilir.

Korunmak için, hatayı günlüğe kaydetmeyi kendi TRY...CATCH'i olan ayrı bir prosedüre kapsülleyin, böylece her zaman "hata işleyici içindeki hata"yı yakalayabilirsiniz.

BEGIN TRY -- ana kod END TRY BEGIN CATCH EXEC LogError @Error = ERROR_MESSAGE(); END CATCH -- LogError prosedürü kendi TRY...CATCH'ini içerir

Hikaye

Proje: Finansal Raporlama. Saklı prosedürlerde TRY...CATCH blokları ekledik, ancak hata meydana geldiğinde kaydedilen parametreleri günlüğe almadık. Sonuç olarak, kritik hataları yakalamada yedekten durumu manuel olarak aramak zorunda kaldık - kök nedeni belirsizdi.


Hikaye

Proje: Belge Yönetimi Otomasyonu (Oracle). EXCEPTION blokunda kullanıcı adını günlüğe almayı unuttuk. Bir haftalık soruşturmadan sonra, birinin kasıtlı olarak belgeleri "kırdığını" keşfettik - bunu yalnızca denetim günlüğündeki dolaylı belirtilere dayanarak anlayabildik.


Hikaye

Proje: E-ticaret. Prosedür bir hata meydana geldiğinde ErrorLog'a hata yazıyordu. Bir seferinde Log tablosu büyüyen bir işlem tarafından kilitlendi ve günlüğe alma girişimi, orijinal nedeni yazan iç içe bir hataya yol açtı ve hata yığını temizlendi. Bu durumu kritik hatalar için ek bir tablo ve çok katmanlı günlüğe alma yöntemi ekleyerek düzelttik.