تنفيذ معالجة أخطاء T-SQL

مكتمل

يشير الخطأ إلى مشكلة أو مشكلة ملحوظة تنشأ أثناء عملية قاعدة بيانات. يمكن إنشاء الأخطاء بواسطة مشغل قاعدة بيانات SQL Server استجابة لحدث أو فشل على مستوى النظام؛ أو يمكنك إنشاء أخطاء التطبيق في التعليمات البرمجية Transact-SQL.

عناصر أخطاء محرك قاعدة البيانات

مهما كان السبب، يتكون كل خطأ من العناصر التالية:

  • رقم الخطأ - رقم فريد يحدد الخطأ المحدد.
  • رسالة الخطأ - نص يصف الخطأ.
  • الخطورة - مؤشر رقمي للخطورة من 1 إلى 25.
  • الحالة - رمز الحالة الداخلية لحالة محرك قاعدة البيانات.
  • Procedure - اسم الإجراء المخزن أو المشغل الذي حدث فيه الخطأ.
  • رقم السطر - عبارة في الدفعة أو الإجراء الذي أنشأ الخطأ.

خطأ في النظام

أخطاء النظام معرفة مسبقا، ويمكنك عرضها في طريقة عرض النظام sys.messages . عند حدوث خطأ في النظام، قد يتخذ SQL Server إجراء علاجيا تلقائيا، اعتمادا على خطورة الخطأ. على سبيل المثال، عند حدوث خطأ عالي الخطورة، قد يأخذ SQL Server قاعدة بيانات دون اتصال أو حتى يوقف خدمة مشغل قاعدة البيانات.

أخطاء مخصصة

يمكنك إنشاء أخطاء في التعليمات البرمجية Transact-SQL للاستجابة للشروط الخاصة بالتطبيق أو لتخصيص المعلومات المرسلة إلى تطبيقات العميل استجابة لأخطاء النظام. يمكن تعريف أخطاء التطبيق هذه بشكل مضمن حيث يتم إنشاؤها، أو يمكنك تعريفها مسبقا في جدول sys.messages جنبا إلى جنب مع الأخطاء التي يوفرها النظام. يجب أن تكون أرقام الأخطاء المستخدمة للأخطاء المخصصة 50001 أو أعلى.

لإضافة رسالة خطأ مخصصة إلى sys.messages، استخدم sp_addmessage. يجب أن يكون مستخدم الرسالة عضوا في أدوار الخادم الثابت sysadmin أو serveradmin.

هذا هو بناء الجملة sp_addmessage:

sp_addmessage [ @msgnum= ] msg_id , [ @severity= ] severity , [ @msgtext= ] 'msg' 
     [ , [ @lang= ] 'language' ] 
     [ , [ @with_log= ] { 'TRUE' | 'FALSE' } ] 
     [ , [ @replace= ] 'replace' ]

فيما يلي مثال على رسالة خطأ مخصصة باستخدام بناء الجملة هذا:

sp_addmessage 50001, 10, N’Unexpected value entered’;

بالإضافة إلى ذلك، يمكنك تعريف رسائل الخطأ المخصصة، يمكن لأعضاء دور خادم مسؤول النظام أيضا استخدام معلمة إضافية ، @with_log. عند التعيين إلى TRUE، سيتم تسجيل الخطأ أيضا في سجل تطبيق Windows. تتم أيضا كتابة أي رسالة مكتوبة إلى سجل تطبيقات Windows إلى سجل أخطاء SQL Server. كن حكيما مع استخدام @with_log الخيار لأن مسؤولي الشبكة والنظام يميلون إلى عدم كره التطبيقات التي هي "الدردشة" في سجلات النظام. ومع ذلك، إذا كان الخطأ يحتاج إلى أن يكون محاصرا بواسطة تنبيه، يجب أولا كتابة الخطأ إلى سجل تطبيق Windows.

إشعار

رفع أخطاء النظام غير مدعوم.

يمكن استبدال الرسائل دون حذفها أولا باستخدام @replace الخيار = "استبدال".

الرسائل قابلة للتخصيص ويمكن إضافة رسائل مختلفة لنفس رقم الخطأ للغات متعددة، استنادا إلى قيمة language_id.

إشعار

الرسائل الإنجليزية language_id 1033.

رفع الأخطاء باستخدام RAISERROR

يمكن استخدام كل من PRINT و RAISERROR لإرجاع المعلومات أو رسائل التحذير إلى التطبيقات. يسمح RAISERROR للتطبيقات برفع خطأ يمكن التقاطه بعد ذلك بواسطة عملية الاستدعاء.

RAISERROR

القدرة على رفع الأخطاء في T-SQL يجعل معالجة الأخطاء في التطبيق أسهل، لأنه يتم إرساله مثل أي خطأ نظام آخر. يتم استخدام RAISERROR ل:

  • المساعدة في استكشاف أخطاء التعليمات البرمجية T-SQL وإصلاحها.
  • تحقق من قيم البيانات.
  • إرجاع الرسائل التي تحتوي على نص متغير.

إشعار

استخدام عبارة PRINT مشابه لرفع خطأ الخطورة 10.

فيما يلي مثال على رسالة خطأ مخصصة باستخدام RAISERROR.

RAISERROR (N'%s %d', -- Message text,
    10, -- Severity,
    1, -- State,
    N'Custom error message number',
    2)

عند تشغيله، فإنه يرجع:

Custom error message number 2

في المثال السابق، %d هو عنصر نائب لرقم %s هو عنصر نائب لسلسلة. بالإضافة إلى ذلك، يجب أن تلاحظ أنه لم يتم ذكر رقم رسالة. عند ظهور أخطاء في سلاسل الرسائل باستخدام بناء الجملة هذا، يكون لها دائما رقم الخطأ 50000.

رفع الأخطاء باستخدام THROW

توفر عبارة THROW طريقة أبسط لرفع الأخطاء في التعليمات البرمجية. يجب أن يكون عدد الأخطاء 50000 على الأقل.

رمى

يختلف THROW عن RAISERROR بعدة طرق:

  • الأخطاء التي يثيرها THROW هي دائما الخطورة 16.
  • لا ترتبط الرسائل التي تم إرجاعها بواسطة THROW بأي إدخالات في sys.sysmessages.
  • تتسبب الأخطاء التي تحدث بواسطة THROW في إحباط المعاملة فقط عند استخدامها بالاقتران مع SET XACT_ABORT ON ويتم إنهاء جلسة العمل.
THROW 50001, 'An Error Occured',0

التقاط رموز الخطأ باستخدام @@Error

تم إنشاء معظم التعليمات البرمجية التقليدية لمعالجة الأخطاء في تطبيقات SQL Server باستخدام @@ERROR. تم تقديم معالجة الاستثناء المنظم في SQL Server 2005 ويوفر بديلا قويا لاستخدام @@ERROR. وستناقش في الدرس التالي. تستند كمية كبيرة من التعليمات البرمجية الحالية لمعالجة أخطاء SQL Server إلى @@ERROR، لذلك من المهم فهم كيفية العمل معها.

@@ERROR

@@ERROR هو متغير نظام يحتوي على رقم الخطأ للخطأ الأخير الذي حدث. أحد التحديات المهمة مع @@ERROR هو أن القيمة التي يحتفظ بها تتم إعادة تعيينها بسرعة عند تنفيذ كل عبارة إضافية.

على سبيل المثال، ضع في اعتبارك التعليمات البرمجية التالية:

RAISERROR(N'Message', 16, 1);
IF @@ERROR <> 0
PRINT 'Error=' + CAST(@@ERROR AS VARCHAR(8));
GO

قد تتوقع أنه عند تنفيذ التعليمات البرمجية، سيتم إرجاع رقم الخطأ في سلسلة مطبوعة. ومع ذلك، عند تنفيذ التعليمات البرمجية، فإنها ترجع:

Msg 50000, Level 16, State 1, Line 1
Message
Error=0

تم رفع الخطأ ولكن الرسالة المطبوعة كانت "Error=0". في السطر الأول من الإخراج، يمكنك أن ترى أن الخطأ، كما هو متوقع، كان بالفعل 50000، مع رسالة تم تمريرها إلى RAISERROR. وذلك لأن عبارة IF التي تتبع عبارة RAISERROR تم تنفيذها بنجاح وتسببت في إعادة تعيين قيمة @@ERROR. لهذا السبب، عند العمل مع @@ERROR، من المهم تسجيل رقم الخطأ في متغير بمجرد رفعه، ثم متابعة المعالجة مع المتغير.

انظر إلى التعليمات البرمجية التالية التي توضح ما يلي:

DECLARE @ErrorValue int;
RAISERROR(N'Message', 16, 1);
SET @ErrorValue = @@ERROR;
IF @ErrorValue <> 0
PRINT 'Error=' + CAST(@ErrorValue AS VARCHAR(8));

عند تنفيذ هذه التعليمة البرمجية، فإنها ترجع الإخراج التالي:

Msg 50000, Level 16, State 1, Line 2
Message
Error=50000

تم الإبلاغ عن رقم الخطأ بشكل صحيح الآن.

مركزية معالجة الأخطاء

هناك مشكلة أخرى مهمة في استخدام @@ERROR لمعالجة الأخطاء وهي أنه من الصعب المركزية داخل التعليمات البرمجية T-SQL. تميل معالجة الأخطاء إلى أن ينتهي بها الأمر مبعثرة في التعليمات البرمجية. سيكون من الممكن مركزية معالجة الأخطاء باستخدام @@ERROR إلى حد ما، باستخدام التسميات وعبارات GOTO. ومع ذلك، سيكون هذا عابس من قبل معظم المطورين اليوم كممارسة ترميز رديئة.

إنشاء تنبيهات الخطأ

بالنسبة لفئات معينة من الأخطاء، قد يقوم المسؤولون بإنشاء تنبيهات SQL Server، لأنهم يرغبون في إعلامهم بمجرد حدوثها. يمكن أن ينطبق هذا حتى على رسائل الخطأ المعرفة من قبل المستخدم. على سبيل المثال، قد تحتاج إلى رفع تنبيه كلما تم تعبئة سجل المعاملات. يستخدم التنبيه بشكل شائع لجلب أخطاء عالية الخطورة (مثل الخطورة 19 أو أعلى) إلى انتباه المسؤولين.

رفع التنبيهات

يمكن إنشاء تنبيهات لرسائل خطأ معينة. تعمل خدمة التنبيه عن طريق تسجيل نفسها كخدمة رد اتصال مع خدمة تسجيل الأحداث. وهذا يعني أن التنبيهات تعمل فقط على الأخطاء المسجلة.

هناك طريقتان لإجراء خطأ رفع تنبيه — يمكنك استخدام الخيار WITH LOG عند رفع الخطأ أو يمكن تغيير الرسالة لجعلها مسجلة عن طريق تنفيذ sp_altermessage. يؤثر خيار WITH LOG على العبارة الحالية فقط. يؤدي استخدام sp_altermessage إلى تغيير سلوك الخطأ لجميع الاستخدامات المستقبلية. تعديل أخطاء النظام عبر sp_altermessage ممكن فقط من SQL Server 2005 SP3 أو SQL Server 2008 SP1 وما بعده.