SQL'de hata işleme ve günlükleme düzeni, karmaşık iş süreçlerinin gelişmesiyle yeni bir popülerlik kazandı. Artık hata meydana geldiğinde yalnızca işlemi durdurmak değil, aynı zamanda hatayı kaydetmek ve mümkünse çalışmaya devam etmek de önemli bir hale geldi. Başlangıçta SQL, gelişmiş try-catch araçlarına sahip değildi ve her veritabanı yönetim sistemi (DBMS) kendi mekanizmalarını sundu.
Soru Tarihi:
Erken SQL standart versiyonları, prosedürlerde hata yakalamak için yerleşik operatörler sunmuyordu. Daha sonra, üreticiler Microsoft SQL Server'da TRY...CATCH veya MySQL'de HANDLER gibi yapılar eklemeye başladı, böylece DB düzeyinde çalışma sürecini daha esnek bir şekilde kontrol edebildik.
Sorun:
Hatalar, hatalı verilerden ve sistemsel nedenlerden kaynaklanabilir. Eğer bir saklı prosedürde hata yakalama ve kaydetme uygulanmazsa, hata ayıklama ve bakım son derece zor hale gelir. Ayrıca, kritik hataları ve işlenmiş hataları ayırt etme yeteneğine sahip olmak gereklidir; aksi takdirde, gereksiz yere iş operasyonunun durdurulmasına neden olabilirsiniz.
Çözüm:
Modern sistemlerde hata toplama ve günlükleme yapıları uygulanmalıdır. Ayrı günlük tabloları oluşturmak, TRY...CATCH (SQL Server) veya DECLARE ... HANDLER (MySQL) kullanmak ve özel hata bilgilerini saklamak, sonrasında hataların nedenlerini incelemek için önemlidir.
Kod örneği (SQL Server):
CREATE PROCEDURE dbo.UpdateCustomer @CustomerID INT, @NewName NVARCHAR(100) AS BEGIN BEGIN TRY UPDATE Customers SET Name = @NewName WHERE CustomerID = @CustomerID; END TRY BEGIN CATCH INSERT INTO ErrorLog (ErrorMessage, ErrorSeverity, ErrorTime) VALUES (ERROR_MESSAGE(), ERROR_SEVERITY(), GETDATE()); THROW; END CATCH END;
Ana özellikler:
TRY...CATCH (veya handler aracılığıyla) tüm hata türlerini yakalamak mümkün müdür?
Hayır, tüm hatalar yakalanamaz; örneğin, sunucu arızaları gibi kritik hatalar yakalanamaz. "Attention" türünde hatalar veya bağlantı kopması gibi hatalar transaction işleme sınırlarını aşar.
Eğer transaction kullanılmazsa hata oluştuğunda prosedürde onaylanmamış değişikliklere ne olur?
Değişiklikler kısmen onaylanır; bazı güncellemeler veritabanına girerken bazıları kaybolabilir. Tutarsızlığı önlemek için her zaman transaction kullanmak önerilir.
BEGIN TRY BEGIN TRANSACTION; --...kod COMMIT; END TRY BEGIN CATCH ROLLBACK; END CATCH
Hata kaydını başka bir bağlamdan yazmak için CATCH bloğundan doğrudan INSERT EXEC kullanılabilir mi?
Her zaman değil: INSERT EXEC bazı bağlamlarda (örneğin, aktif bir transaction varsa) yasaktır, bu da ikinci seviye hatalara neden olabilir. Hata ayrıntılarını yerel olarak toplamak ve ardından bunları tekil INSERT olarak kaydetmek daha iyidir.
Müşteri, yalnızca RAISERROR ile günlükleme yapmadan bir mantık gerçekleştirdi, bu nedenle hatalar kaydedilmedi ve analiz edilmedi.
Artılar:
Eksiler:
TRY...CATCH ve ErrorLog tablosu kullanıldı; zaman, hata kodu, kullanıcı, metin ve iz kaydı kaydedildi.
Artılar:
Eksiler: