سؤال

هل من الممكن إنشاء وظيفة من داخل برنامج تثبيت Magento؟لدي حاليا الكود التالي:

$installer = $this;
$installer->startSetup();
$installer->run("
         DROP function IF EXISTS {$this->getTable('getLatestActivity')};
         CREATE FUNCTION {$this->getTable('getLatestActivity')} (activityid int) RETURNS int(11)
         BEGIN

         set @rank = 0;

         set @matchingId := (select id from (
         SELECT   @rank := @rank+1 AS rank, t_act.id, t_act.date
         FROM      activityupdates ut_act
         LEFT JOIN activityupdates AS t_act ON t_act.ticked = 1
             AND t_act.date <= ut_act.date AND t_act.customer_id = ut_act.customer_id AND t_act.type = ut_act.type
         WHERE ut_act.id = activityid
         ORDER BY t_act.date DESC
         )ranked
         where ranked.rank = 1);
         return @matchingId;
         END;
     ");

لكني حصلت على استثناء SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 4 - ليست مفيدة للغاية.

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

$installer->run("

         DROP function IF EXISTS `{$this->getTable('getLatestActivity')}`;
         DELIMITER $$
         CREATE FUNCTION `{$this->getTable('getLatestActivity')}` (activityid int) RETURNS int(11)
         BEGIN

         set @rank = 0;

         set @matchingId := (select id from (
         SELECT   @rank := @rank+1 AS rank, t_act.id, t_act.date
         FROM      activityupdates ut_act
         LEFT JOIN activityupdates AS t_act ON t_act.ticked = 1
             AND t_act.date <= ut_act.date AND t_act.customer_id = ut_act.customer_id AND t_act.type = ut_act.type
         WHERE ut_act.id = activityid
         ORDER BY t_act.date DESC
         )ranked
         where ranked.rank = 1);
         return @matchingId;
         END$$

         DELIMITER ;

     ");

خطأ: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER $$ CREATE FUNCTION getLatestActivity (activityid int)

هل كانت مفيدة؟

المحلول

Mage_Core_Model_Resource_Setup::run() يقبل استعلامات متعددة، ويقسم الوسيطة المحددة (بيان SQL) بفواصل منقوطة.يؤدي هذا إلى تقسيم نص الوظيفة إلى عدة مكالمات منفصلة.يصبح إعلان الوظيفة غير مكتمل ويفشل إنشاء الوظيفة مع ظهور رسالة الاستثناء المحددة.

بالإضافة إلى ذلك، بدلاً من استخدام عميل MySQL CLI (أو PHPMyAdmin) مباشرة، فإن تحديد محدد يؤدي إلى PDOException. نيلز بريوس تلقى الحل من القائمة البريدية Zend_Db منذ عدة سنوات:

  1. لا تقلق بشأن DELIMITER، فأنت لست بحاجة إليه.
  2. يجب عليك DROP وCREATE في بيانين منفصلين.
  3. تجاوز طريقة الاستعلام ZF الافتراضية.

لتلخيص ذلك، سيؤدي المقتطف التالي إلى إنشاء الوظيفة:

$this->getConnection()->query("DROP function IF EXISTS `{$this->getTable('getLatestActivity')}`");
$this->getConnection()->query("
CREATE FUNCTION `{$this->getTable('getLatestActivity')}` (activityid int) RETURNS int(11)
BEGIN
    set @rank = 0;
    set @matchingId := (select id from (
        SELECT   @rank := @rank+1 AS rank, t_act.id, t_act.date
        FROM      activityupdates ut_act
        LEFT JOIN activityupdates AS t_act ON t_act.ticked = 1
            AND t_act.date <= ut_act.date
            AND t_act.customer_id = ut_act.customer_id
            AND t_act.type = ut_act.type
        WHERE ut_act.id = activityid
        ORDER BY t_act.date DESC
    ) ranked
    where ranked.rank = 1);
    return @matchingId;
END;
");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى magento.stackexchange
scroll top