Frage

Ist es möglich, eine Funktion aus einem Magento-Installationsskript heraus zu erstellen?Ich habe derzeit folgenden Code:

$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;
     ");

Aber ich bekomme eine Ausnahme ausgelöst 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 - nicht sehr hilfreich.

Um dies in PHPMyAdmin zum Laufen zu bringen, musste ich Zeilen bezüglich DELIMITERS hinzufügen, aber ich denke, das ist ein Nachteil der GUI und nicht der FUNCTION, die sie erfordert.Wenn ich sie einbeziehe, erhalte ich lediglich eine Ausnahme bezüglich der Definition eines 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 ;

     ");

Fehler: 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)

War es hilfreich?

Lösung

Mage_Core_Model_Resource_Setup::run() akzeptiert mehrere Abfragen und teilt das angegebene Argument (SQL-Anweisung) durch Semikolons auf.Dies führt dazu, dass der Funktionskörper in mehrere separate Aufrufe aufgeteilt wird.Die Funktionsdeklaration ist dann unvollständig und die Funktionserstellung schlägt mit der angegebenen Ausnahmemeldung fehl.

Darüber hinaus führt die Definition eines Trennzeichens im Gegensatz zur direkten Verwendung des MySQL-CLI-Clients (oder PHPMyAdmin) zu a PDOException. Nils Preuß habe eine Lösung von der erhalten Zend_Db-Mailingliste vor einigen Jahren:

  1. Machen Sie sich keine Sorgen wegen DELIMITER, Sie brauchen es nicht.
  2. Sie müssen DROP und CREATE in zwei separaten Anweisungen ausführen.
  3. Umgehen Sie die standardmäßige ZF-Abfragemethode.

Zusammenfassend führt das folgende Snippet zur Erstellung der Funktion:

$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;
");
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top