【问题标题】:MySQL - What is wrong with this trigger?MySQL - 这个触发器有什么问题?
【发布时间】:2013-12-06 01:34:42
【问题描述】:

我正在尝试创建此触发器,但 UPDATE 行出现错误。

DROP TRIGGER IF EXISTS upd_signedup;

CREATE TRIGGER upd_signedup
BEFORE INSERT ON tbl_users
FOR EACH ROW
BEGIN
  UPDATE tbl_user_stats SET signups = signups + 1;
END

编辑:我已将分隔符设置为 $$ 但无法创建此触发器:

 drop trigger if exists upd_signedup$$

 CREATE TRIGGER upd_signedup
 BEFORE INSERT ON tbl_users
 FOR EACH ROW
 BEGIN
  UPDATE tbl_user_stats SET signups = signups + 1$$
 END

【问题讨论】:

  • 你用什么 MySQL 客户端执行这个?您是否根据客户的需要更改了语句分隔符?
  • phpMyAdmin。我没有更改分隔符。
  • 您收到的错误信息是什么?
  • #1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取正确的语法,以便在第 5 行的 '' 附近使用
  • 我相信 PHPMyAdmin 有一个字段来设置分隔符。请参阅stackoverflow.com/questions/8080681/… 以了解您的语句应该是什么样的示例(其中$$ 是这些示例中选择的分隔符)

标签: mysql triggers


【解决方案1】:

您似乎误解了在定义触发器时使用 DELIMITER 的概念。

;(分号)是一个常规分隔符,一个可执行语句结束的指示符。 但是,当您定义触发器或存储过程时,您会使用多个可执行语句(如变量声明和 SQL 语句)来定义主体。

使用;表示SQL引擎该语句已经结束,是时候编译执行了。但是除非trigger的body或者存储过程的ENDs,否则trigger/sp body的内部语句执行是没有意义的。为了停止处理此类语句,我们使用自定义的DELIMITER,例如//$$,或者您喜欢并且经常不使用在触发器/sp 定义的主体部分中的内容。然后,MySQL 会理解语句仅在找到您自定义的 DELIMITER 时才结束,例如 $$//

一个例子如下所示:

mysql>
mysql> set @cnt=0;
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> -- drop trigger if exists trig_bef_del_on_tbl;
mysql> delimiter //
mysql> create trigger trig_bef_del_on_tbl before delete on tbl
    ->   for each row begin
    ->     set @cnt = if(@cnt is null, 1, (@cnt+1));
    ->
    ->     /* for cross checking save loop count */
    ->     insert into rows_affected values ( @cnt );
    ->   end;
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> delimiter ;
mysql>
mysql> -- now let us test the delete operation
mysql> delete from tbl where i like '%1%';
Query OK, 3 rows affected (0.02 sec)

参考

【讨论】:

    【解决方案2】:

    触发器的主体只有一个命令,因此您可以使用这种简单的语法,无需 BEGIN-END 子句和 DELIMITER:

    CREATE TRIGGER upd_signedup
      BEFORE INSERT ON tbl_users
      FOR EACH ROW
      UPDATE tbl_user_stats SET signups = signups + 1;
    

    【讨论】:

    • 如果我想最终在 UPDATE 语句之前添加一个 SELECT 语句,我需要 BEGIN-END 子句吗?
    • 是的,您需要添加该子句。请注意,SELECT 和 UPDATE 语句可以合并到一个通用的 UPDATE 语句中。
    猜你喜欢
    • 2011-02-11
    • 1970-01-01
    • 2012-04-26
    • 2022-01-21
    • 2011-08-16
    • 1970-01-01
    • 2017-12-24
    • 2014-11-29
    相关资源
    最近更新 更多