إنشاء إجراءات مخزنة

مكتمل

تعد الإجراءات المخزنة واحدة من أقوى الأدوات في 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

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