انتقل إلى محتوى الدرس
الدرس 58
دورة MySQL

المشغلات التلقائية Triggers والأحداث المجدولة Events في MySQLMySQL Automated Triggers and Scheduled Events

تعلّم المشغلات التلقائية Triggers والأحداث المجدولة Events في MySQL بأسلوب MySQL 8 الحديث مع أمثلة استعلامات SQL وتطبيقات تفاعلية.
أقسام الدرس
6
الأمثلة
5
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
7
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع

المشغّل التلقائي (Trigger) في محرك MySQL 8.4 هو كائن برمجي مخزن يرتبط بجدول محدد ويعمل تلقائياً استجابةً لحدث تعديل بيانات (INSERT أو UPDATE أو DELETE) دون الحاجة لاستدعائه يدوياً من التطبيق. يعمل المشغل دائماً على مستوى كل صف متأثر بالتعديل (FOR EACH ROW)، بحيث إذا عدّلت جملة UPDATE خمسة صفوف، ينفذ الخادم جسم المشغل خمس مرات متتالية.

ينقسم توقيت تشغيل المشغل إلى نوعين رئيسيين: المشغل القبلي (BEFORE Trigger) ويعمل قبل حفظ التعديل الفعلي على القرص، مما يجعله مثالياً لتنقية المدخلات وضبط القيم الافتراضية والتحقق من صحة البيانات قبل كتابتها؛ والمشغل البعدي (AFTER Trigger) ويعمل بعد نجاح كتابة الصف وتوليد المفاتيح التلقائية، مما يجعله الخيار الأنسب لتسجيل حركات التدقيق (Audit Logs) وتحديث الجداول الإحصائية التابعة.

المشغلات التلقائية Triggers والأحداث المجدولة Events في MySQL

مخطط معماري يوضح آلية عمل المشغلات التلقائية BEFORE وAFTER وسجلات NEW وOLD ورفع الأخطاء بـ SIGNAL والأحداث المجدولة بـ CREATE EVENT.
المشغلات التلقائية Triggers والأحداث المجدولة Events في MySQL
المشغلات التلقائية Triggers والأحداث المجدولة Events في MySQL
SQL
DELIMITER $$
CREATE TRIGGER trg_customers_before_insert
BEFORE INSERT ON customers
FOR EACH ROW
BEGIN
    SET NEW.email = LOWER(TRIM(NEW.email));
    IF NEW.loyalty_points < 0 THEN
        SET NEW.loyalty_points = 0;
    END IF;
END$$
DELIMITER ;

للوصول إلى بيانات الصف الذي يجري تعديله داخل جسم المشغل، يوفر محرك MySQL 8.4 سجلّين افتراضيين هما OLD وNEW. تعتمد إتاحة هذين السجلين على نوع العملية: في مشغلات INSERT يتوفر السجل NEW فقط لأن الصف لم يكن موجوداً من قبل؛ وفي مشغلات DELETE يتوفر السجل OLD فقط لقراءة بيانات الصف المحذوف؛ أما في مشغلات UPDATE فيتوفر السجلان معاً حيث يمثل OLD.col القيمة السابقة قبل التحديث ويمثل NEW.col القيمة الجديدة.

انتبه لقاعدة القراءة والكتابة الصارمة: السجل OLD يكون للقراءة فقط دائماً في جميع المشغلات، بينما يمكن تعديل قيم NEW.col عبر الأمر SET داخل مشغلات BEFORE INSERT وBEFORE UPDATE حصرياً، ويصبح للقراءة فقط في مشغلات AFTER لأن الصف يكون قد كُتب بالفعل في الجدول.

SQL
DELIMITER $$
CREATE TRIGGER trg_orders_after_update
AFTER UPDATE ON orders
FOR EACH ROW
BEGIN
    IF OLD.amount <> NEW.amount THEN
        INSERT INTO order_price_logs (order_id, old_amt, new_amt, changed_on)
        VALUES (OLD.order_id, OLD.amount, NEW.amount, CURRENT_TIMESTAMP);
    END IF;
END$$
DELIMITER ;

محاكي المشغلات والأحداث التفاعلي

إلى جانب تنقية البيانات وتسجيل التدقيق، تُستخدم مشغلات BEFORE لفرض قواعد التحقق المركبة التي تتجاوز قدرات قيود CHECK العادية. عندما يكتشف المشغل قيمة مخالفة لقواعد العمل (مثل محاولة خفض سعر طلب مدفوع أو إدخال كمية سالبة)، يمكنه إيقاف العملية بالكامل وإرجاع رسالة خطأ واضحة للتطبيق باستخدام جملة SIGNAL SQLSTATE '45000'.

الرمز القياسي '45000' مخصص في معيار SQL للأخطاء المعرَّفة من قِبل المستخدم (Unhandled User-Defined Exception)، وتحدد الخاصية MESSAGE_TEXT نص الرسالة التوضيحية التي ستظهر للمطور أو تُلتقط في كود التطبيق، مما يلغي تعديل الصف تلقائياً ويحافظ على سلامة الجدول.

SQL
DELIMITER $$
CREATE TRIGGER trg_orders_validate_amount
BEFORE UPDATE ON orders
FOR EACH ROW
BEGIN
    IF NEW.amount < 0.00 THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'Order amount cannot be negative';
    END IF;
END$$
DELIMITER ;

بينما تعمل المشغلات التلقائية استجابةً لتعديل الصفوف، تعمل الأحداث المجدولة (Scheduled Events) في MySQL 8.4 استجابةً للوقت تماماً مثل مهام الجدولة الزمنية (Cron Jobs) ولكن داخل خادم قاعدة البيانات نفسه. يدير هذه الأحداث خيط معالجة خلفي مدمج يُسمى مجدول الأحداث (Event Scheduler)، ويكون مفعّلاً افتراضياً في MySQL 8.4 (القيمة event_scheduler = ON).

يمكنك إنشاء حدث يُنفَّذ لمرة واحدة فقط في توقيت محدد مستقبلاً باستخدام الصيغة ON SCHEDULE AT timestamp (مثل إغلاق عرض ترويجي في نهاية الشهر أو توليد تقرير جرد لمرة واحدة). وبمجرد انتهاء تنفيذ الحدث الأحادي، يحذفه المحرك تلقائياً من قاموس البيانات ما لم تضف العبارة ON COMPLETION PRESERVE للاحتفاظ بتعريفه.

SQL
-- Check Event Scheduler status and create a one-time event
SHOW VARIABLES LIKE 'event_scheduler';

CREATE EVENT ev_close_promo_campaign
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 HOUR
ON COMPLETION PRESERVE
DO
    UPDATE promotions SET is_active = 0
    WHERE expires_at <= CURRENT_TIMESTAMP;

الاستخدام الأكثر شيوعاً للأحداث في الأنظمة الإنتاجية هو أتمتة المهام الدورية المتكررة (Recurring Events) باستخدام الصيغة ON SCHEDULE EVERY n unit (مثل EVERY 1 DAY أو EVERY 15 MINUTE). يمكنك أيضاً تقييد فترة سريان التكرار بتحديد وقت البداية STARTS timestamp ووقت النهاية ENDS timestamp.

كما يمكنك إيقاف حدث دوري مؤقتاً دون حذفه عبر الأمر ALTER EVENT ev_name DISABLE; ثم إعادة تفعيله لاحقاً بـ ENABLE، واستعراض جميع المشغلات والأحداث المسجلة عبر SHOW TRIGGERS وSHOW EVENTS، وحذف ما انتهت الحاجة إليه بأمان عبر DROP TRIGGER IF EXISTS وDROP EVENT IF EXISTS.

SQL
CREATE EVENT ev_daily_token_cleanup
ON SCHEDULE EVERY 1 DAY
STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
    DELETE FROM auth_tokens
    WHERE expires_at < CURRENT_TIMESTAMP - INTERVAL 7 DAY;

SHOW EVENTS LIKE 'ev_%';
DROP TRIGGER IF EXISTS trg_customers_before_insert;
DROP EVENT IF EXISTS ev_close_promo_campaign;

يلخص الجدول المرجعي التالي الفروق الجوهرية بين المشغلات القبلية (BEFORE) والمشغلات البعدية (AFTER) والأحداث المجدولة (EVENTS) في MySQL 8.4:

الكائن المخزنمحفز التشغيلالوصول لـ NEW وOLDالاستخدام الهندسي الأمثل
مشغل BEFOREقبل تنفيذ INSERT أو UPDATE أو DELETE على الصف.يمكن قراءة وتعديل NEW.col، وقراءة OLD.col.تنقية المدخلات والتحقق الصارم وإطلاق SIGNAL SQLSTATE '45000'.
مشغل AFTERبعد نجاح حفظ التعديل على الصف وتوليد المعرف التلقائي.قراءة فقط لكلا السجلين NEW وOLD.كتابة سجلات التدقيق (Audit Logs) في جداول المراجعة المنفصلة.
حدث ONE TIME EVENTON SCHEDULE AT timestampلا يوجد (يعمل على مستوى الجداول بالوقت).أتمتة مهمة مستقبلية لمرة واحدة مثل إغلاق حملة ترويجية.
حدث RECURRING EVENTON SCHEDULE EVERY n unitلا يوجد (يتكرر دورياً في الخلفية).تنظيف الجلسات المنتهية وأرشفة السجلات وتحديث الإحصائيات الدورية.
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

أتقنت في هذا الدرس إنشاء المشغلات التلقائية BEFORE وAFTER على مستوى الصف، واستخدام السجلين NEW وOLD للتنقية والتدقيق، وإيقاف العمليات الخاطئة بـ SIGNAL SQLSTATE '45000'، وجدولة المهام الزمنية في الخلفية بـ CREATE EVENT.

الخطوة التالية والدرس القادم

في الوحدة القادمة سننتقل إلى دوال النوافذ التحليلية (Window Functions) باستخدام OVER وPARTITION BY لإجراء التحليلات المتقدمة والترتيب التراكمي.

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 Row Trigger (FOR EACH ROW) المشغل التلقائي للصفوف (Row Trigger)
كائن برمجي مخزن يرتبط بجدول محدد وينفذ تلقائياً قبل أو بعد كل صف يتأثر بأوامر INSERT أو UPDATE أو DELETE.
للمراجعة
02 NEW and OLD Pseudo-Records السجلان الافتراضيان (NEW / OLD)
مرجعان داخل المشغل التلقائي يتيحان قراءة قيم أعمدة الصف الجديدة (NEW) والقديمة (OLD) أثناء عملية التعديل.
للمراجعة
03 SIGNAL SQLSTATE '45000' إطلاق الاستثناء (SIGNAL SQLSTATE)
العبارة القياسية المستخدمة داخل المشغلات والإجراءات لإطلاق خطأ مخصص وإلغاء عملية التعديل المخالفة لقواعد البيانات.
للمراجعة
04 Scheduled Event (CREATE EVENT) الحدث الزمني المجدول (Scheduled Event)
مهمة خلفية زمنية يديرها مجدول أحداث MySQL لتعمل في توقيت محدد أو تتكرر دورياً كل فترة زمنية لصيانة الجداول.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات2

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 2 مفهومةأول بطاقة، أول خطوة
01 DML DML
Data Manipulation Language
لغة معالجة البيانات وتشمل أوامر INSERT وUPDATE وDELETE التي تطلق المشغلات التلقائية
للمراجعة
02 SQLSTATE SQLSTATE
SQL State Error Code
رمز حالة قياسي من خمسة محارف يحدد فئة الخطأ في محرك SQL مثل 45000 للأخطاء المخصصة
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. أنشئ مشغل AFTER UPDATE على جدول orders يقارن بين OLD.amount وNEW.amount ويسجل التغيير في جدول order_price_logs.

  2. استكشف السيناريوهات الثلاثة في المحاكي التفاعلي للمشغلات والأحداث وافحص سجل التدقيق ورسالة خطأ SIGNAL ومخرجات SHOW EVENTS.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

4أسئلة 1أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي4 أسئلة تنتظرك
01

في أي توقيت للمشغل التلقائي يُسمح بتعديل قيم الأعمدة الجديدة عبر SET NEW.column_name قبل حفظ الصف؟

اختر الإجابة الأدق وفق قواعد محرك MySQL 8.4.

02

ما السجلات الافتراضية المتاحة للقراءة داخل مشغل مرتبط بحدث UPDATE في MySQL 8.4؟

اختر الإجابة الأدق وفق قواعد محرك MySQL 8.4.

03

ما العبارة المستخدمة داخل مشغل BEFORE لإلغاء عملية التعديل وإرجاع رسالة خطأ مخصصة للعميل؟

اختر الإجابة الأدق وفق قواعد محرك MySQL 8.4.

04

ما العبارة التي تحدد جدولاً زمنياً متكرراً يعمل مرة كل يوم داخل أمر CREATE EVENT؟

اختر الإجابة الأدق وفق قواعد محرك MySQL 8.4.