MySQL функция в скрипте установщика
-
13-12-2019 - |
Вопрос
Можно ли создать функцию в рамках сценария установщика 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;
");
Но я получаю исключение, брошенный генеракодицетагкод - не очень полезен.
Чтобы получить эту работу в phpmyadmin, мне пришлось добавить линии относительно разделителей, но я думаю, что это недостаток графического интерфейса, а не функции, требующей их.Если я включил их, я просто получаю исключение о определении разделителя.
$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 '' at line 4
Решение
Mage_Core_Model_Resource_Setup::run()
принимает несколько запросов, разделение данного аргумента (SQL-оператор) в запятее. Это приводит к разбитому телу функции на несколько отдельных вызовов. Декларация функции затем неполная, а создание функций не удается с заданным сообщением исключения.
Дополнительно, в отличие от использования клиента MySQL CLI (или PHPMYADMIN) напрямую, определяя разделитель приводит к генеракодичениюCode. Nils Preuß получил решение от список рассылки Zend_DB несколько лет назад :
- Не беспокойтесь о разделитете, вам это не нужно.
- Вы должны бросить и создавать в двух отдельных высказываниях.
- обойти метод запроса 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;
");
.