【问题标题】:MySQL: Set session var to NULL on SQLExceptionMySQL:在 SQLException 上将会话变量设置为 NULL
【发布时间】:2013-04-01 21:00:04
【问题描述】:

我在表“a”上有一个插入前触发器,它基本上复制并转换查询以将插入到表“b”中。这是此触发器的伪代码示例:

FOR EACH ROW
BEGIN
  IF @inserting IS NULL THEN
    SET @inserting = 1;
    INSERT INTO b SET
      col1 = NEW.col1
      col2 = NEW.cola
      col3 = some_stored_proc(NEW.col3);
    SET @inserting = NULL;
  END IF
END

但是,您可能会注意到,如果 INSERT 失败,@inserting 将保留为 1。如果插入到表“b”失败,我需要确保将其设置回 NULL,同时导致表“a”上的原始插入也失败(以免两者之间的数据不匹配)。

有没有办法做到这一点?

【问题讨论】:

  • 为了防止混淆,这个触发器的原因实际上是允许一个新的模式,同时维护一些旧应用程序依赖的旧模式。
  • 是否可以选择 cgi 脚本?
  • @marabutt:老实说,我不知道,但考虑到我没有编写 CGI 脚本的经验,我更倾向于说不,并在我看之前用稍微熟悉的触发器探索可能性进入那个。

标签: mysql sql triggers sqlexception


【解决方案1】:

经过一番研究,我发现DECLARE...HANDLER 和RESIGNAL 可以解决这个问题。

FOR EACH ROW
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    SET @inserting = NULL;
    RESIGNAL;
  END;
  IF @inserting IS NULL THEN
    SET @inserting = 1;
    INSERT INTO b SET
      col1 = NEW.col1
      col2 = NEW.cola
      col3 = some_stored_proc(NEW.col3);
    SET @inserting = NULL;
  END IF;
END

DECLARE EXIT HANDLER FOR SQLEXCEPTION 允许您对 SQL 异常执行语句(并在完成时退出当前过程)。

RESIGNAL 将传递错误。

【讨论】:

  • 但我不明白的是,如果在插入b 时出现异常,它只会退出触发器并且无论如何都会重置@inserting。您的进程在异常 (AFAIK) 后不会循环。
  • @Sebas @inserting 设置为 1,INSERT INTO b 失败,SET @inserting = NULL 由于异常而永远不会运行。 @inserting 在会话的其余部分保留为 1。
  • 我很好奇:你用这个会话变量做什么?
  • @Sebas 阻止表 b 上执行反向操作的反向触发器由于此触发器而触发。
  • 我明白了。那么我猜你的解决方案很好。也许您可以改用“INSERT IGNORE INTO b ...”,但是您不会看到异常。由你决定。
猜你喜欢
  • 2016-11-21
  • 2020-02-17
  • 2013-01-27
  • 2018-06-26
  • 2013-03-29
  • 2016-01-13
  • 1970-01-01
  • 2013-08-21
  • 1970-01-01
相关资源
最近更新 更多