【问题标题】:Multiple Create Trigger query in PDOPDO 中的多个创建触发器查询
【发布时间】:2018-11-30 16:40:01
【问题描述】:

我正在尝试在 PDO 中运行以下 SQL 字符串。我可以确认代码确实直接在 MySQL 中执行,但在 PHP PDO 中运行它会引发错误。

我了解DELIMITER $$ 在 PDO 接口上不可用。根据how to execute mysql command DELIMITER,将分隔符留在查询之外应该没问题。

查询字符串:

CREATE DEFINER=CURRENT_USER TRIGGER `M5_tblMVTransactionVat_VatInsert` AFTER INSERT ON `M2_tblVatRevisions`
FOR EACH ROW BEGIN
  UPDATE M5_tblMVTransactionVat
  SET M5_tblMVTransactionVat.vatID = 1;

END

CREATE DEFINER=CURRENT_USER TRIGGER `M5_tblMVTransactionVat_VatUpdate` AFTER UPDATE ON `M2_tblVatRevisions`
FOR EACH ROW BEGIN
  UPDATE M5_tblMVTransactionVat
  SET M5_tblMVTransactionVat.vatID = 2;

END

通过简单的 PDO::exec 或 PDOStatement::prepare(使用 PDO::ATTR_EMULATE_PREPARES = 1)运行会导致错误

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 'CREATE
DEFINER=CURRENT_USER TRIGGER `M5_tblMVTransactionVat_VatUpdate` AFTER
UPD' at line 8

我已经确认通过 PDO 一次只运行一个 Create Trigger 不会导致相同的错误并且触发器已成功创建。 .

如何在一个 PDO 连接上执行多个创建触发器查询?

【问题讨论】:

    标签: php mysql pdo innodb


    【解决方案1】:

    不要一次执行多个语句。

    没有理由这样做,it causes problems if you try

    MySQL 的前工程总监曾经告诉我,multi_query 没有理由存在,它只会造成伤害(这是我的解释)。

    在对 PDO::exec() 的调用中执行每个 CREATE TRIGGER 语句更简单、更安全。

    【讨论】:

    • 好的,那么如果我想通过 PHP PDO 在数据库上应用大量创建触发器作为数据库初始化序列,则需要我将它们放入不同的文件中,或者自己编写分隔符/解析器?
    • 是的。你觉得mysql 客户端是怎么做到的?
    • 我以为是通过 MySQL CLI,它有一个内置的解析器?编辑:既然你提到了它,我看到像 DELETE VIEWS 这样的东西被列为历史记录中的单独语句。
    • 客户端有一个非常简单的解析器:它读取到 DELIMITER 字符串,然后将读取到的内容发送到服务器以作为单个语句执行。然后它会一直读取到下一个 DELIMITER 并重复该过程。
    • 然后把它写成一个可重用的PHP包来运行SQL脚本,并作为开源产品发布,这样其他人就不必重新发明这个轮子了。到目前为止,我从未见过真正有效的。
    【解决方案2】:

    你想在一个文件中包含一堆初始化的东西吗?那为什么还要费心 PHP 呢?做

    mysql ... -e "source foo.sql"
    

    好的,你希望 PHP 运行一些东西吗?然后从 php 执行此操作:

    execcute('mysql ... -e "source foo.sql"');
    

    但是,您最好按下舱门——这对于黑客来说是一种极好的破坏方式。

    【讨论】:

    • 似乎这比编写我自己的客户端来解释 SQL 文件更容易。谢谢!这是对我问题的解决方案,但不是“技术上”对我问题的回答。所以我将选择“你不能”作为 bill-karwin 的答案
    • @EatonEmmerich - 这个论坛上的许多问题都没有说明 原始 问题,而只是说明了在碰壁之前发生的问题。 (我喜欢并同意比尔的回答。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    • 2012-08-04
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多