T-SQL’de hataların işleyiş şeklini ve temel hata işleme yöntemlerini öğrendik, daha gelişmiş bir hata işleme yöntemine göz atmanın zamanı geldi. Yapılandırılmış exception handling SQL Server 2005’te tanıtılmıştır. Bu bölümde kullanılışını, avantajlarını ve diğer yönlerini öğreneceğiz.

TRY/CATCH Bloğu

Yapılandırılmış exception handling, SQL Server 2005 sürümüyle T-SQL diline girdiğinde zaten bir süredir üst düzey dillerin bir parçasıydı.

Yapılandırılmış exception handling, @@ERROR’dan daha güçlü bir yapıdır. Yazılan kodun hata işlemeyle kodlarıyla dolup taşmasını önlemekle birlikte ve merkezileştirmeye katkı sağlamaktadır. Hata işleme kodunun merkezileştirilmesi, hata işlemeden ziyade amaca daha fazla odaklanabileceğiniz anlamına gelmektedir.

Yapılandırılmış exception handling kullanılırken, hataya neden olabilecek kod, TRY bloğu içine yerleştirilir. Oluşturulan TRY blokları da BEGIN TRY ve END TRY bloğu içerisine yerleştirilir.

Bir catchable (yakalanabilir) hata oluşursa (ki çoğu hata yakalanabilir), işlem akışı CATCH bloğuna geçer. CATCH bloğu ise BEGIN CATCH ve END CATCH ifadeleri tarafından çevrelenen bir dizi T-SQL ifadesidir. Ayrıca END TRY’ın ardından hemen BEGIN CATCH’in gelmesi gerekir.

Mevcut Sınırlamalar

Üst düzey dillerde bulunan try/catch/finally yapısı genellikle kullanılan kaynakları (örn. text dosyası) dolaylı yoldan serbest bırakmak için kullanılmaktadır. İkinci olarak, finally yapısının T-SQL’de eşdeğeri bulunmamaktadır.

Hata İşleme Fonksiyonları

CATCH bloğuyla oluşan hata hakkında her bilgiye erişilebilmektedir. Bu duruma CATCH bloğu içerisinde kullanılan sp’ler gibi yapılar da dahildir.     

@@ERROR ile kod yazarken bu değişken tarafından tutulan değer, bir sonraki ifade yürütülür yürütülmez sıfırlandığını hatırlıyorsunuzdur. T-SQL’de yapılandırılmış exception handling’in bir diğer avantajı da burada ortaya çıkmaktadır. Kullanıcıya bir takım hata işleme fonksiyonlarının sağlanmış olması ve bunların CATCH bloğu boyunca değerlerinin korunmasıdır. Bu sayede kod yazarken blok içerisinde hatayla ilgili bilgilere her an erişebilmek mümkündür.

Catchable ve Non-Catchable Hatalar

TRY/CATCH blokları @@ERROR ile yakalanan çok daha geniş hata aralığını yakalamaya olanağı tanır. Fakat bazı hata türleri yakalanamaz.

Aynı scope içerisinde yakalanamayan hatalar, genellikle bir scope’da yakalanabilmektedir. Örneğin, TRY/CATCH bloğunun olduğu sp’de oluşan bir hata sp içerisinde değil de sp’yi çağıran koddaki TRY/CATCH bloğunla yakalanabilir.

Yaygın Non-catchable Hatalar

Non-catchable hataların yaygın örnekleri şunlardır:

  • Bir batch’in derlenmesine engel olan syntax hataları gibi derleme hataları.
  • Genellikle geciktiirlmiş ad çözümlemesi ile ilgili ifade düzeyinde recompile sorunları. Örneğin bilinmeyen bir tabloyu kullanan sp oluşturabilirsiniz. Bu durumda hata yalnızca çalıştırılan procedure tablonun adını bir objectid ile çözümlemeye çalıştığında basılacaktır.

THROW ile Hataları Yeniden Fırlatma

THROW ifadesi herhangi bir parametre olmadan CATCH bloğunda kullanılırsa, kodun CATCH ile yakalanması neden olan hatayı yeniden basar. Bu tekniği, hataları yakalayıp ayrıntılarını log’a kaydeder ve ardından hatayı client programına yollayarak veri tabanında hata işlenir ve error log tutulabilir.

SQL Server’ın ilk sürümlerinde, sistem hatası basma yolu yoktu. THROW, basılması gereken sistem hatasını belirleyemese de CATCH bloğunda parametre olmadan kullanılırsa hem sistem hem de kullanıcı hatalarını yeniden fırlatmaktadır.

Yönetilen Koddaki Hatalar

SQL CLR entegrasyonuyla yönetilen kod SQL Server içinde yürütülebilmektedir. C# ve VB gibi üst düzey .NET dillerinde detaylı exception handling yöntemi bulunmaktadır. Hatalar standart .NET try/catch/finally blokları kullanılarak yakalanabilir.

Genel olarak koddaki hataları olabildiğince yakalamayı isteriz. Ayrıca kod içerisinde işlenmeyen hatalar, çalıştırılan T-SQL koduna geri gönderilmektedir. Yönetilen kodda oluşan herhangi bir hata SQL Server’a geri döndüğünde, 6522 hatası şeklinde görünür. Hata ve hatanın gerçek sebebi sarmalanır ve böylece son kullanıcıya hatanın gerçek sebebi yansıtılmaz.

Son olarak, yönetilen koddaki hatalar az bir olasılıkla da olsa kod içerisinde SqlCommand ile RAISERROR T-SQL ifadesini çalıştırması olabilir.

Kaynak:
How to implement error handling in SQL Server
SQL Server 2012: Structured Error Handling Mechanism