Installerスクリプトの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;
");
.
しかし、私は例外をスローした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で実行するには、区切り者に関して行を追加しなければなりませんでしたが、私はそれらを必要とする機能よりもGUIの欠点があると思います。私がそれらを含めるならば、代わりに区切り文字の定義について例外を得るだけです。
$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
につながります。 NILS PREUSS Zend_dbメーリングリスト数年前:
- 区切り文字を心配しないでください、あなたはそれを必要としません。
- 2つの別のステートメントでドロップして作成する必要があります。
- デフォルトの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;
");
.