it-swarm.asia

استدعاء إجراء مخزن من الزناد

لقد قمت بإنشاء إجراء مخزن في الخلية باستخدام بناء الجملة التالي.

DROP PROCEDURE IF EXISTS `sp-set_comment_count`;

DELIMITER $$

CREATE PROCEDURE `sp_set-comment_count` (IN _id INT)
BEGIN
   -- AC   - AllCount
   DECLARE AC INT DEFAULT 0;

   SELECT COUNT(*) AS ac
     INTO AC
     FROM usergroups AS ug
LEFT JOIN usergroup_comments AS ugm ON ugm.`gid` = ug.`id`
LEFT JOIN mediagallery AS dm ON ugm.mid = dm.`id`
    WHERE dm.`status` NOT IN (200, 201, 202, 203, 204, 205)
      AND ug.`id` = _id;

   UPDATE usergroups
      SET allCount = AC,
    WHERE usergroups.`id` = _id;

END $$
DELIMITER ;

لمعلوماتك ، قمت بتبسيط الإجراء المخزن بشكل كبير ولكني أعرف أنه يعمل بدون أي مشاكل.

ما أود أن أكون قادرًا على فعله هو إعداد مشغل من usergroup_comments يعمل على هذا النحو.

DROP TRIGGER IF EXISTS `usergroups_comments_insert` 

CREATE TRIGGER `usergroups_comments_insert` AFTER INSERT ON `usergroups_comment`
    FOR EACH ROW
    BEGIN
       CALL sp-set-comment_count(NEW.`gid`);
    END;

ولكن لسبب ما في كل مرة أقوم فيها الخلية بإلقاء خطأ في وجهي أقل من مفيد يفيد أن هناك خطأ في بناء الجملة في السطر 4.

لقد قمت بتمشيط وثائق mysql ووجدت بعض المعلومات حول قيود المشغلات ولكن وجدت أنها معقدة إلى حد ما.

http://dev.mysql.com/doc/refman/5.1/en/stored-program-restrictions.html

اي افكار ستكون مفيدة.

17
Mark D

لذلك اتضح أن هذه هي المشكلة التي ابتليت بها لبضع ساعات صدق أو لا تصدق.

يمكنني بسهولة تحديد إجراء يسمى sp_set-comment_count. ولكن عند استدعاء الإجراء المذكور ، فإنه لا يعمل بنفس الطريقة.

CALL sp_set-comment_count (يمكنني افتراض أن هذا فقط لأن الخادم يفسر - على أنه ناقص).

لقد قمت منذ ذلك الحين بتغيير اسم الإجراء المخزن لاستخدام الشرطات السفلية فقط ويبدو أنه قد حل كل شيء.

8
Mark D

هناك سبب كبير يمنعك من استدعاء الإجراءات المخزنة من داخل المشغلات.

المشغلات هي ، بطبيعتها ، إجراءات مخزنة. أفعالها يصعب التراجع عنها . حتى إذا كانت جميع الجداول الأساسية هي InnoDB ، فسوف تواجه حجمًا نسبيًا من أقفال الصف المشتركة والتقطع المزعج من أقفال الصف الحصرية. سيكون هذا هو الحال إذا كانت مشغلات التلاعب بالجداول مع ركود INSERTs و UPDATEs لأداء المهام الثقيلة MVCC داخل كل مكالمة إلى الزناد .

لا تنس أن المشغلات تتطلب النفقات العامة. في الواقع ، وفقًا لـ برمجة الإجراءات المخزنة MySQL ، الصفحة 256 تحت عنوان "Trigger Overhead" تقول ما يلي:

من المهم أن تتذكر أنه ، بحكم الضرورة ، تضيف المشغلات زيادة إلى عبارة DML التي تنطبق عليها. سيعتمد المقدار الفعلي للنفقات العامة على طبيعة المشغل ، ولكن --- أثناء تنفيذ جميع مشغلات MySQL لكل صف - يمكن أن يتراكم الحمل السريع للبيانات التي تعالج أعدادًا كبيرة من الصفوف. لذلك يجب عليك تجنب وضع أي عبارات SQL باهظة الثمن أو التعليمات البرمجية الإجرائية في المشغلات.

يوجد شرح موسع لحمل الزناد على الصفحات 529-531. توضح النقطة الختامية من هذا القسم ما يلي:

الدرس هنا هو هذا: نظرًا لأن رمز المشغل سيتم تنفيذه مرة واحدة لكل صف يتأثر بعبارة DML ، يمكن أن يصبح المشغل بسهولة أهم عامل في أداء DML. يجب أن تكون التعليمات البرمجية داخل نص المشغل خفيفة الوزن قدر الإمكان - وعلى وجه الخصوص - يجب دعم أي عبارات SQL في المشغل بواسطة الفهارس كلما أمكن ذلك.

شرحت جوانب سيئة أخرى من المشغلات في منشور سابق.

ملخص [~ # ~] [~ # ~]

أود أن أوصي بشدة بعدم استدعاء أي إجراءات مخزنة من مشغل ، حتى لو سمحت MySQL بذلك. يجب عليك التحقق من القيود الحالية لـ MySQL 5.5 .

24
RolandoMySQLDBA

إذا كان يشير إلى خطأ في بناء الجملة ، فمن الأرجح أنك نسيت تغيير المحدد (كما فعلت في الإجراء المخزن). لذا عليك

DELIMITER $$
CREATE TRIGGER `usergroups_comments_insert` AFTER INSERT ON `usergroups_comment`
FOR EACH ROW
BEGIN
   CALL sp_set_count(NEW.`gid`);
END;
$$
5
a1ex07

يبدو أن الفاصلة بعد AC خطأ في بناء الجملة:

UPDATE usergroups
   SET allCount = AC,
 WHERE ........
1
user22800