Pregunta

¿Es posible crear una función desde un script de instalación de Magento?Actualmente tengo el siguiente código:

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

Pero me lanzan una excepción 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 - no es muy útil.

Para que esto se ejecute en PHPMyAdmin, tuve que agregar líneas sobre DELIMITADORES, pero creo que eso es un inconveniente de la GUI en lugar de la FUNCIÓN que los requiere.Si los incluyo, obtengo una excepción al definir un 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 ;

     ");

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

¿Fue útil?

Solución

Mage_Core_Model_Resource_Setup::run() acepta múltiples consultas, dividiendo el argumento dado (declaración SQL) en punto y coma.Esto lleva a que el cuerpo de la función se divida en múltiples llamadas separadas.Entonces, la declaración de la función está incompleta y la creación de la función falla con el mensaje de excepción proporcionado.

Además, a diferencia de utilizar el cliente CLI de MySQL (o PHPMyAdmin) directamente, definir un delimitador conduce a un PDOException. Nils Preuß recibió una solución del Lista de correo de Zend_Db Hace unos pocos años:

  1. No te preocupes por DELIMITER, no lo necesitas.
  2. Debe SOLTAR y CREAR en dos declaraciones separadas.
  3. Omita el método de consulta ZF predeterminado.

En resumen, el siguiente fragmento conducirá a la creación de la función:

$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;
");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top