MySQL 分隔符语句错误

Moe*_*ius 1 mysql playframework

我正在尝试在 mysql 中运行以下脚本:

DELIMITER $$$
DROP TRIGGER IF EXISTS invoice_line_insert
$$$
CREATE TRIGGER invoice_line_insert AFTER INSERT
ON invoice_line FOR EACH ROW
BEGIN
    IF NEW.type = "DELIVERY" THEN
        UPDATE invoice
        SET invoice.etdelivery_amount = invoice.etdelivery_amount + NEW.amount
        WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;
    ELSE
        UPDATE invoice
        SET invoice.etexpense_amount = invoice.etexpense_amount + NEW.amount
        WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;
    END IF;
    UPDATE invoice
    SET invoice.vatamount = (NEW.amount * ((
                SELECT vat.rate
                FROM vat
                WHERE vat.id_vat = NEW.vat_id_vat
    ) / 100)) + invoice.vatamount
    WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;

    UPDATE invoice
    SET invoice.itamount = invoice.vatamount +
            invoice.etdelivery_amount +
            invoice.etexpense_amount
    WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;
END
$$$
Run Code Online (Sandbox Code Playgroud)

当我在 mySql Workbench 中运行它时,它工作正常,但是当 play 2 自动运行它时(在一个名为 2.sql 的文件中)我收到以下错误:

您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行 [ERROR:1064, SQLSTATE:42000] 附近的“DELIMITER $$$ DROP TRIGGER IF EXISTS invoice_line_insert $$$ CREATE TRIGGER invo”附近使用正确的语法,同时尝试运行此 SQL 脚本:

我在互联网上读到分隔符语句仅适用于特定的 gui,而不是每次都适用。真的吗 ?为什么 ?如何解决它,因为我需要分隔符语句?

谢谢你的帮助。

Sun*_*dhu 5

这似乎是Play 框架 2.0 演变和创建触发器的副本 (请注意,在我看来,更好的答案是 Roger 在 2013 年 5 月 24 日发布的那个,即上面的链接)

进化脚本文本中不能使用“分隔符”;我似乎找不到任何关于为什么会这样的文件。但也许这与“分隔符”不是 SQL 语句而是 SQL 属性的事实有关。

但是,在Play 2 文档Evolutions 部分有一个解决方案:

Play 将您的 .sql 文件拆分为一系列以分号分隔的语句,然后再对数据库逐个执行。因此,如果您需要在语句中使用分号,请输入 ;; 代替 ;。例如, INSERT INTO punctuation(name, character) VALUES ('分号', ';;');。

所以在你的情况下,

  1. 删除“分隔符”属性,并
  2. 用 ”;;” 代替 ”;” 为您的内部SQL 语句,以防止 Play 2 解析器单独执行这些内部 SQL 语句。

这是我在 Play 2.3 和 mysql 14.14 Distrib 5.5.40 (Ubuntu 12.04LTS) 中成功测试的示例:

DROP TRIGGER IF EXISTS SOFTWARE_INSERT_CT_TRIGGER;
CREATE TRIGGER SOFTWARE_INSERT_CT_TRIGGER
BEFORE INSERT ON SOFTWARE
FOR EACH ROW
BEGIN
  IF NEW.CREATED_TIME = '0000-00-00 00:00:00' THEN
    SET NEW.CREATED_TIME = NOW();;
  END IF;;
END;
Run Code Online (Sandbox Code Playgroud)

对于您的 SQL 脚本,以下内容应适用于 Play 2.1 及更高版本(请注意,我尚未对其进行测试):

DROP TRIGGER IF EXISTS invoice_line_insert;
CREATE TRIGGER invoice_line_insert AFTER INSERT
ON invoice_line FOR EACH ROW
BEGIN
  IF NEW.type = "DELIVERY" THEN
    UPDATE invoice
    SET invoice.etdelivery_amount = invoice.etdelivery_amount + NEW.amount
    WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;;
  ELSE
    UPDATE invoice
    SET invoice.etexpense_amount = invoice.etexpense_amount + NEW.amount
    WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;;
  END IF;;
  UPDATE invoice
  SET invoice.vatamount = (NEW.amount * ((
    SELECT vat.rate
    FROM vat
    WHERE vat.id_vat = NEW.vat_id_vat
  ) / 100)) + invoice.vatamount
  WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;;

  UPDATE invoice
  SET invoice.itamount = invoice.vatamount +
    invoice.etdelivery_amount +
    invoice.etexpense_amount
  WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;;
END;
Run Code Online (Sandbox Code Playgroud)