SQL Server’da hata işleme, Transact-SQL kodu üzerinde kontrol sahibi olmamızı sağlar. Örneğin, işler ters gittiğinde, bu konuda bir şeyler yapma ve muhtemelen tekrar doğru yapma şansımız olur. SQL Server hata işleme, sadece bir şey olduğunu günlüğe kaydetmek kadar basit veya bir hatayı düzeltmeye çalışıyor olabiliriz. SQL SQL hata mesajlarının nasıl anlam ifade edemeyeceğini ve anlaşılması zor olabileceğini bildiğimiz için hata SQL dilinde bile tercüme edilebilir. Neyse ki, bu mesajları kullanıcılara, geliştiricilere vb. kişilere aktarmak için daha anlamlı bir şeye çevirme şansımız var.
Bu makalede, TRY… CATCH deyimine daha yakından bakacağız: sözdizimi, nasıl göründüğü, nasıl çalıştığı ve bir hata oluştuğunda neler yapılabilir. Ayrıca, farklı bir bakış açısı olarak, bir SQL Server durumunda, temel olarak SQL Server’ın hataların ele alınma şekli olan bir grup T-SQL deyimi / bloğu kullanılarak açıklanacaktır. Bu, bunu yapmanın çok basit ama yapılandırılmış bir yoludur ve birçok durumda oldukça yardımcı olabilir.
Bunun da ötesinde, kafa karıştırıcı hata mesajlarını insanların anlayabileceği biraz daha anlamlı bir şeye dönüştürmenin harika bir yolu olan kendi özel hata mesajlarımızı oluşturmak için kullanılabilecek bir RAISERROR işlevi de vardır.
TRY… CATCH kullanarak hataları işleme
Sözdizimi şöyle görünür. Yazmak oldukça basit. İki kod bloğumuz var:
1 2 3 4 5 6 7 8 | BEGIN TRY --Hata olabilecek SQL kodları END TRY BEGIN CATCH --Hata olduğunda çalıştırılacak bölüm END CATCH |
BEGIN TRY ve END TRY arasındaki herhangi bir şey, bir hata için izlemek istediğimiz koddur. Dolayısıyla, bu TRY ifadesinde bir hata olsaydı, kontrol derhal CATCH ifadesine aktarılır ve daha sonra kod satır satır yürütülmeye başlardı.
Şimdi, CATCH deyiminin içinde hatayı düzeltmeye, hatayı rapor etmeye veya hatta günlüğe kaydetmeye çalışabiliriz, bu yüzden ne zaman olduğunu, kullanıcı adını, tüm faydalı şeyleri günlüğe kaydederek kimin yaptığını biliyoruz. Hatta sadece CATCH deyiminde bulunan bazı özel verilere erişebiliriz:
ERROR_NUMBER – Hatanın dahili numarasını döndürür
ERROR_STATE – Kaynak hakkındaki bilgileri döndürür
ERROR_SEVERITY – Bilgi hatalarından DBA kullanıcısının düzeltebileceği hatalara kadar her şey hakkındaki bilgileri döndürür.
ERROR_LINE – Bir hatanın oluştuğu satır numarasını döndürür
ERROR_PROCEDURE – Saklı yordam veya işlevin adını döndürür
ERROR_MESSAGE – En gerekli bilgileri döndürür ve hatanın mesaj metnidir.
SQL Server hata işleme söz konusu olduğunda tek gereken budur. Her şey basit bir TRY ve CATCH deyimi ile yapılabilir ve zor olabileceği tek bölüm işlemlerle uğraştığımız zamandır. Neden? Çünkü bir BEGIN TRANSACTION varsa, her zaman bir COMMIT veya ROLLBACK işlemi ile bitmelidir. Sorun, başladıktan sonra ancak taahhütte bulunmadan veya geri dönmeden önce bir hata oluşmasıdır. Bu özel durumda, CATCH deyiminde, bir işlemin yüklenebilir bir durumda olup olmadığını kontrol etmeyi sağlayan, daha sonra geri alma veya işlemeye karar vermemize izin veren özel bir işlev vardır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | BEGIN TRY -- Sıfıra bölünme hatası SELECT 1 / 0 AS Error; END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_STATE() AS ErrorState, ERROR_SEVERITY() AS ErrorSeverity, ERROR_PROCEDURE() AS ErrorProcedure, ERROR_LINE() AS ErrorLine, ERROR_MESSAGE() AS ErrorMessage; END CATCH; GO |
Bu nasıl göründüğüne ve nasıl çalıştığına bir örnektir. BEGIN TRY’de yaptığımız tek şey, 1’i 0’a bölmek, elbette bir hataya neden olacak. Dolayısıyla, bu kod bloğuna ulaşılır ulaşılmaz, kontrolü CATCH bloğuna aktaracak ve daha sonra daha önce bahsettiğimiz yerleşik işlevleri kullanarak tüm özellikleri seçecek. Komut dosyasını yukarıdan yürütürsek, elde ettiğimiz budur:
İki SELECT ifadesi nedeniyle iki sonuç aldık: ilki 1’i 0 bölme, bu da hataya neden olur ve ikincisi bize bazı sonuçlar veren aktarılmış kontrol. Soldan sağa, ErrorNumber, ErrorState, ErrorSeverity; bu durumda hiçbir yordam yoktur (NULL), ErrorLine ve ErrorMessage.
Şimdi biraz daha anlamlı bir şey yapalım. Bu hataları izlemek akıllıca bir fikirdir. Hataya neden olan şeyler yine de yakalanmalı ve en azından kayıt altına alınmalıdır. Ayrıca, bu kaydedilmiş tablolara tetikleyiciler koyabilir ve hatta bir e-posta hesabı ayarlayabilir ve bir hata oluştuğunda insanları bilgilendirmek için biraz yaratıcı olabilirsiniz.
Aşağıdaki komut dosyası, izleme verilerini depolamak için kullanılabilen DB_Errors adlı bir tablo oluşturur:
1 2 3 4 5 6 7 8 9 10 11 12 13 | CREATE TABLE DB_Errors (ErrorID INT IDENTITY(1, 1), UserName VARCHAR(100), ErrorNumber INT, ErrorState INT, ErrorSeverity INT, ErrorLine INT, ErrorProcedure VARCHAR(MAX), ErrorMessage VARCHAR(MAX), ErrorDateTime DATETIME) GO |
Burada basit bir kimlik sütunu, ardından kullanıcı adı var, bu yüzden hatayı kimin oluşturduğunu biliyoruz ve geri kalanı daha önce listelediğimiz yerleşik işlevlerden tam bilgi.
Şimdi veritabanından özel bir saklı yordamı değiştirelim ve oraya bir hata işleyici koyalım:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ALTER PROCEDURE dbo.satis @musterino INT, @urunno INT, @adet SMALLINT, @satisid UNIQUEIDENTIFIER OUTPUT AS SET @satisid= NEWID() BEGIN TRY INSERT INTO satir SELECT @satisid, @urunid, @musteriid, @adet END TRY BEGIN CATCH INSERT INTO dbo.DB_Errors VALUES (SUSER_SNAME(), ERROR_NUMBER(), ERROR_STATE(), ERROR_SEVERITY(), ERROR_LINE(), ERROR_PROCEDURE(), ERROR_MESSAGE(), GETDATE()); END CATCH GO |
Bu saklı yordamı değiştirmek, yalnızca bu durumda saklı yordam içindeki tek deyim çevresinde hata işlemeyi sarar. Bu saklı yordamı çağırır ve bazı geçerli verileri iletirsek, hataları bulmamız ve hataları raporlamamız daha kolay olur.
Umarım bu makale sizin için bilgilendirici olmuştur ve okuduğunuz için teşekkür ederim.
Yorum Yap