【问题标题】:mysql trigger : column not part of the update is not nullmysql触发器:不属于更新的列不为空
【发布时间】:2016-09-07 09:42:24
【问题描述】:

mysql V 5.6

嗨,我在更新之前遇到了一个触发器问题:在一张表上,我有一个标记为 tinyint,而不是 null,默认值 1。我有一个更新前触发器,只要行更新,就会将此标志设置为 1。但是,我还需要在一个进程中将标志显式设置为 0,所以我尝试了

create trigger t BEFORE UPDATE on table for each row
BEGIN
IF new.flag is NULL THEN  
    set new.flag = 1
 END IF;

问题:new.flag 永远不会为空。 使用检查

IF new.flag is NULL THEN  
    set new.flag = 1
ELSEIF new.flag = 0 THEN
    set new.flag = 3
END IF;

每当我更新表而不在更新查询中包含标志时,将列设置为 3。更糟糕的是,我无法检查空字符串以将标志置为 1,因为如果使用 select ('' = 0),则返回 true:

IF new.flag is NULL OR new.flag = '' THEN  
    set new.flag = 1
END IF;

我永远不能明确地将标志设置为 0 。在 NEW 中,不属于更新的列不应该为 null 吗?我该怎么办,是要更改 mysql 配置吗?

谢谢

【问题讨论】:

  • new 将包含该行在更新后将具有的值(以及 old 之前的值)。如果您没有在查询中设置它,它将具有之前的值(new 不是您在更新查询中使用的列列表)。你可以使用例如set flag = 3 在您的更新查询中作为您希望在触发器中将其设置为 0 的标记。或者您可能想要更改您的逻辑,常见的更新标记是例如带有on update current_timestamptimestamp 字段。
  • @Solarflare ha,在绑定器中设置一个假值,然后设置为 0 似乎可以做到:IF new.flag_indexation_required = 3 THEN set new.flag_indexation_required = 0;否则设置 new.flag_indexation_required = 1;万一;您可以添加您的答案以便我接受吗?

标签: mysql triggers


【解决方案1】:

NEW 包含更新后该行将具有的所有列的值,而不仅仅是您在更新查询中明确使用的值。

要告诉触发器您要显式重置该值,您可以使用其他未使用(但有效)的值来标记该信息,然后在触发器中采取相应的行动,例如,在您的触发器中,使用(假设已签名小号)

IF new.flag = -1 THEN  
  set new.flag = 0;
ELSE
  set new.flag = 1;
END IF;

然后在您的update 查询中,

update table set flag = -1;

将值设置为0,任何其他值,或根本不使用查询中的该列,将其设置为1

有一种替代且更常见的方法,无需触发器,其工作方式类似于您的标志。您可以使用列

last_update datetime default null on update current_timestamp;

此列中的nullflag = 0 具有相同的含义,任何其他值都与flag = 1 具有相同的含义。它们是自动设置的。如果你想重置你的“标志”,你可以简单地使用

update table set last_update = null;

您的触发方法当然会非常完美。只需确保在某处记录该行为即可。

【讨论】:

    猜你喜欢
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多