إنشاء إجراءات مخزنة
تعد الإجراءات المخزنة واحدة من أقوى الأدوات في SQL Server لتغليف منطق الأعمال وتحسين أداء التطبيقات. عند إنشاء إجراءات مخزنة، تبني كتل كود قابلة لإعادة الاستخدام تنفذ على الخادم، مما يقلل من حركة مرور الشبكة ويوحد منطق الوصول إلى البيانات.
فهم الإجراءات المخزنة
الإجراء المخزن هو مجموعة مترجمة من عبارات T-SQL يخزنها SQL Server وينفذها كوحدة واحدة. على عكس الاستعلامات غير المخططة التي ترسلها إلى الخادم في كل مرة، فإن الإجراءات المخزنة مترجمة مسبقا وتحسين، مما يعني أنها تعمل أسرع في التنفيذات اللاحقة.
تستخدم إجراءات مخزنة لتغليف منطق الأعمال المعقد، وفرض قواعد التحقق من صحة البيانات، والتحكم في كيفية تفاعل التطبيقات مع قاعدة بياناتك. على سبيل المثال، بدلا من السماح بالوصول المباشر إلى الجدول، يمكنك إنشاء إجراءات مخزنة تتحقق من صحة المدخلات، وتطبق قواعد الأعمال، وتسجل التغييرات قبل تعديل البيانات.
تأتي فوائد الأداء من تخزين خطط الاستعلام المؤقت. مع الاستعلامات غير المخططة، يجب على SQL Server تحليل وتحسين كل استعلام في كل مرة. مع الإجراءات المخزنة، يتم تخزين خطة التنفيذ مؤقتا بعد التشغيل الأول، مما يقلل من الحمل الزائد للعمليات المتكررة.
إنشاء إجراءات مخزنة أساسية
يبدأ إنشاء إجراء مخزن بالعبارة CREATE PROCEDURE متبوعة بمنطق T-SQL الخاص بك. تحدد اسم الإجراء باستخدام معرف مؤهل من المخطط، مما يحسن الوضوح والأداء.
CREATE PROCEDURE dbo.GetCustomerOrders
AS
BEGIN
SET NOCOUNT ON;
SELECT
OrderID,
CustomerID,
OrderDate,
TotalAmount
FROM dbo.Orders
ORDER BY OrderDate DESC;
END
تمنع العبارة SET NOCOUNT ON إرسال رسالة عن عدد الصفوف المتأثرة إلى العميل. يقلل هذا من حركة مرور الشبكة ويحسن الأداء، خاصة عندما تنفذ العملية عدة عبارات.
عند إنشاء الإجراءات، استخدم الكلمات BEGIN المفتاحية وكلمات END مفتاحية لتعريف جسم الإجراءات بوضوح. هذا يجعل الكود أكثر قابلية للقراءة ويساعد في منع الأخطاء عند إضافة أو تعديل المنطق لاحقا.
العمل مع المعلمات
تجعل المعاملات الإجراءات المخزنة مرنة وقابلة لإعادة الاستخدام. أنت تحدد معلمات إدخال لقبول القيم من التطبيق المستدعي، ومعلمات الإخراج لإعادة القيم إلى المستدعي.
تستخدم معلمات الإدخال رمز @ متبوعا باسم المعلمة ونوع البيانات. يمكنك توفير قيم افتراضية لجعل المعلمات اختيارية:
CREATE PROCEDURE dbo.GetCustomerOrdersByDate
@CustomerID int,
@StartDate datetime = NULL,
@EndDate datetime = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT
OrderID,
OrderDate,
TotalAmount
FROM dbo.Orders
WHERE CustomerID = @CustomerID
AND (@StartDate IS NULL OR OrderDate >= @StartDate)
AND (@EndDate IS NULL OR OrderDate <= @EndDate)
ORDER BY OrderDate DESC;
END
معلمات الإخراج تتيح لك إرجاع القيم إلى التطبيق المستدعي. تعرفها باستخدام الكلمة المفتاحية OUTPUT :
CREATE PROCEDURE dbo.CalculateOrderTotal
@OrderID int,
@TotalAmount decimal(10,2) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT @TotalAmount = SUM(Quantity * UnitPrice)
FROM dbo.OrderDetails
WHERE OrderID = @OrderID;
RETURN 0;
END
عند استدعاء إجراء بمعلمات الإخراج، يجب عليك إعلان متغير لاستقبال القيمة واستخدام OUTPUT الكلمة المفتاحية في الجملة EXECUTE .
تنفيذ معالجة الأخطاء
تشمل الإجراءات المخزنة القوية معالجة الأخطاء لإدارة الحالات غير المتوقعة والحفاظ على سلامة البيانات. تقوم بتنفيذ معالجة الأخطاء باستخدام TRY...CATCH الكتل، والتي تعمل بطريقة مشابهة لمعالجة الاستثناءات في لغات البرمجة الأخرى.
CREATE PROCEDURE dbo.InsertCustomerOrder
@CustomerID int,
@OrderDate datetime,
@TotalAmount decimal(10,2)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION;
-- Validate customer exists
IF NOT EXISTS (SELECT 1 FROM dbo.Customers WHERE CustomerID = @CustomerID)
BEGIN
RAISERROR('Customer does not exist.', 16, 1);
END
-- Insert order
INSERT INTO dbo.Orders (CustomerID, OrderDate, TotalAmount)
VALUES (@CustomerID, @OrderDate, @TotalAmount);
COMMIT TRANSACTION;
RETURN 0;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
DECLARE @ErrorMessage nvarchar(4000) = ERROR_MESSAGE();
DECLARE @ErrorSeverity int = ERROR_SEVERITY();
DECLARE @ErrorState int = ERROR_STATE();
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
RETURN -1;
END CATCH
END
TRY الكتلة تحتوي على منطقك الرئيسي، بينما تتعامل الكتلة CATCH مع أي أخطاء تحدث. يمكنك استخدام وظائف النظام مثل ERROR_MESSAGE()، ERROR_SEVERITY()، والتقاط ERROR_STATE() تفاصيل الأخطاء وتمريرها إلى التطبيق الذي يتصل به.
تحقق @@TRANCOUNT دائما قبل التراجع عن المعاملات في CATCH البلوك. هذا يمنع حدوث أخطاء إذا كانت المعاملة قد أكملت بالفعل أو لم تبدأ.
تطبيق أفضل الممارسات
اتباع أفضل الممارسات المعتمدة عند إنشاء إجراءات مخزنة يضمن أنها قابلة للصيانة وآمنة وذات أداء.
استخدم الأسماء المؤهلة للمخطط
استخدم أسماء معتمدة من المخطط لجميع الكائنات. هذا يزيل الغموض ويحسن الأداء من خلال تجنب عبء حل المخططات الزائدة:
-- Good
SELECT * FROM dbo.Orders
-- Avoid
SELECT * FROM Orders
تنفيذ التحقق من صحة المعلمات
نفذ التحقق من صحة المعلمات في بداية إجراءك. فشل بسرعة عندما تكون المدخلات غير صالحة بدلا من معالجة البيانات السيئة:
IF @CustomerID IS NULL OR @CustomerID <= 0
BEGIN
RAISERROR('CustomerID must be a positive integer.', 16, 1);
RETURN -1;
END
تجنب SELECT *
تجنب SELECT * ذلك في كود الإنتاج. اذكر الأعمدة بشكل صريح لمنع المشاكل عند تغير هياكل الجداول ولتحسين أداء الاستعلام:
-- Good
SELECT OrderID, CustomerID, OrderDate FROM dbo.Orders
-- Avoid
SELECT * FROM dbo.Orders
استخدم أسماء ذات معنى
استخدم أسماء ذات معنى تصف ما يفعله الإجراء. أضف فعلا يشير إلى العملية (الحصول عليه، إدراج، تحديث، حذف، حساب):
CREATE PROCEDURE dbo.GetActiveCustomersByRegion
CREATE PROCEDURE dbo.UpdateCustomerAddress
CREATE PROCEDURE dbo.DeleteExpiredOrders
تجنب البادئة sp_
لا تستخدم البادئة sp_ لإجراءات المخزنة. يحتفظ master SQL Server بهذه البادئة لإجراءات النظام المخزنة في قاعدة البيانات. عندما تسمي إجراء ب sp_، يقوم master SQL Server أولا بالبحث قبل التحقق من قاعدة البيانات الحالية، مما يضيف عبئا زائدا غير ضروري:
-- Good
CREATE PROCEDURE dbo.GetCustomerOrders
-- Avoid
CREATE PROCEDURE dbo.sp_GetCustomerOrders
البناء على هذه الممارسات يساعدك على إنشاء إجراءات مخزنة يمكن لفريقك فهمها وصيانتها والثقة بها لأداء العمل بشكل موثوق في بيئات الإنتاج.