在 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 FUNCTION fn_Get_HardinessZone ( ZipCode VARCHAR( 15 ) ) 返回整数 DETERMINISTIC BEGIN DECLARE 结果整数; MySQL 说:#1064 - 你的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 4 行的 '' 附近使用正确的语法 @GregDemetrick 请参阅我发布的关于更改分隔符的说明。以下是明确的说明:***.com/a/8081096/961455 您的解决方案适用于 SQL 部分,因为我能够让它在 phpMySQL 下运行并创建函数。在插入过程中,我遇到了***.com/questions/6983447/… 现在提到的一个问题。感谢您的帮助!

以上是关于在 Magento 中为模块创建数据库函数的主要内容,如果未能解决你的问题,请参考以下文章

从贝宝重定向到 magento 管理模块

自定义 Magento 模块

Magento CURD

Magento 1.9 创建新的 Hello World 模块

Magento2开发教程 - 如何向数据库添加新表

Magento:如何为部分付款创建模块?