在 Magento 中为模块创建数据库函数
Posted
技术标签:
【中文标题】在 Magento 中为模块创建数据库函数【英文标题】:Creating a database function within Magento for a module 【发布时间】:2012-07-20 03:04:57 【问题描述】:我在 Magento 中有一个工作模块,它模仿了我们在安装之外使用的一些自定义代码。该模块目前向数据库添加 5 个表来存储信息,并且我已将 Admin 扩展为 CRUD 信息。这里的最终目标是将大部分自定义编程转移到 Magento 中。
目前,我们的自定义代码位于 Magento 外部并访问一个单独的数据库。该数据库具有相同的 5 个表、一个存储过程和 4 个函数。我现在想做的是将存储过程和函数移动到 Magento 的数据库中,并更改自定义代码以从 Magento 的数据库中调用所有数据。但是,我似乎无法弄清楚应该如何为 Magento 设置“CREATE FUNCTION”调用才能正确执行它。
我使用的 SQL 是:
DROP FUNCTION IF EXISTS $this->getTable('fn_Get_HardinessZone');
CREATE FUNCTION $this->getTable('fn_Get_HardinessZone')(IN ZipCode varchar()) RETURNS integer AS
DECLARE Result integer;
BEGIN
SELECT MAX(Zone) into Result
FROM AMI_zones
WHERE (Hfzip <= LEFT(ZipCode, 5)) AND (Htzip >= LEFT(ZipCode, 5));
if Result is null or Result < 1 or (Result > 11 and Result <> 99) Then
/*if the left most character is alpha, then set the zone to 98 for Canada*/
if Left(zipCode, 1) >= 'A' and LEFT(zipcode,1) <= 'Z' THEN
set result = 98;
else
set Result = 99;
End if;
END if;
RETURN Result;
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 'IN ZipCode varchar()) RETURNS'
那么,格式化 SQL 调用以在模块的安装/更新脚本中运行以将函数或存储过程插入 Maganeto 的数据库的正确方法是什么?
【问题讨论】:
你如何执行这个查询? 只是为了确认一下,您已将函数标记为与您的表同名? @tim 这包含在我模块中的 sql_update.php 文件中。所以当我将模块修改为相同的数字时它会被执行。 @trickyzter 不确定我是否完全理解,但此时数据库中不存在任何函数。函数中调用的表是正确的,并且确实存在于系统中。 $this->getTable 组件只是在脚本执行时回显名称 fn_Get_HardinessZones。 你能把IN
(就在函数名后面)去掉试试看吗?
【参考方案1】:
问题出在你的 SQL 语句上:
您的 SQL 语法有错误;检查手册... 正确的语法在附近使用
'
IN ZipCode varchar()) RETURNS
'
我建议通过 PhpMyAdmin 或在命令行上运行 SQL,直到正确为止,然后通过 Magento 运行它。此手册页描述了 CREATE FUNCTION
的语法:http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html。在 mysql 客户端(或 PhpMyAdmin)中测试存储过程 / 函数时,请确保 change the delimiter 以便正确解释函数体中的分号。
下面的 SQL 对我有用。我从你原来的陈述中改变的事情是:
IN
不允许在函数声明中使用 (IN ZipCode varchar())
我被要求明确声明varchar
的长度
DECLARE
属于函数内部
我猜你的函数是DETERMINISTIC
,这意味着它对于相同的输入参数总是会产生相同的结果。如果不是这种情况,请从 RETURNS
行中删除 DETERMINISTIC
试一试:
DROP FUNCTION IF EXISTS $this->getTable('fn_Get_HardinessZone');
CREATE FUNCTION $this->getTable('fn_Get_HardinessZone') (ZipCode VARCHAR(15))
RETURNS INTEGER DETERMINISTIC
BEGIN
DECLARE result INTEGER;
SELECT MAX(Zone) INTO result
FROM AMI_zones
WHERE (Hfzip <= LEFT(ZipCode, 5)) AND (Htzip >= LEFT(ZipCode, 5));
IF result IS NULL OR result < 1 OR (result > 11 AND result <> 99) THEN
/* if the left most character is alpha, then set the zone to 98 for Canada */
IF LEFT(ZipCode, 1) >= 'A' AND LEFT(ZipCode, 1) <= 'Z' THEN
SET result = 98;
ELSE
SET result = 99;
END IF;
END IF;
RETURN result;
END;
【讨论】:
这似乎是正确的方向,但是当我在插入 Magento 之前通过 phpMyAdmin 运行它进行测试时,我收到了这个错误,并且查询中没有空格出现这个错误:错误 SQL 查询:CREATE FUNCTIONfn_Get_HardinessZone
( ZipCode VARCHAR( 15 ) ) 返回整数 DETERMINISTIC BEGIN DECLARE 结果整数; MySQL 说:#1064 - 你的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 4 行的 '' 附近使用正确的语法
@GregDemetrick 请参阅我发布的关于更改分隔符的说明。以下是明确的说明:***.com/a/8081096/961455
您的解决方案适用于 SQL 部分,因为我能够让它在 phpMySQL 下运行并创建函数。在插入过程中,我遇到了***.com/questions/6983447/… 现在提到的一个问题。感谢您的帮助!以上是关于在 Magento 中为模块创建数据库函数的主要内容,如果未能解决你的问题,请参考以下文章