在mysql触发器中,有没有一种方法可以知道哪个列正在更新?

在mysql触发器中,有没有一种方法可以知道哪个列正在更新?,mysql,database-trigger,Mysql,Database Trigger,mysql是否有一条语句可以帮助我知道触发器中正在修改的列 我已经试过了: DELIMITER // CREATE TRIGGER trigger AFTER UPDATE ON myTable FOR EACH ROW IF OLD.ID != NEW.ID THEN INSERT INTO backupTable (ID,back_ID) values (NEW.ID,OLD.ID); E

mysql是否有一条语句可以帮助我知道触发器中正在修改的列

我已经试过了:

DELIMITER //
CREATE TRIGGER trigger
    AFTER UPDATE ON myTable
    FOR EACH ROW
        IF OLD.ID != NEW.ID THEN
            INSERT INTO backupTable
                (ID,back_ID) values (NEW.ID,OLD.ID);
        END IF
//
DELIMITER;

但是我的老师说,这是另一种比在MySQL的行级触发器中比较
OLD.ID
NEW.ID
更有效的方法,因为无法直接确定语句中引用了哪些列。MySQL不允许我们访问导致触发的语句

UPDATE
触发器中,我们可以访问列的“NEW”和“OLD”值,并进行比较

给出这样的陈述:

UPDATE myTable SET fo = IFNULL(fo,0) + 1 WHERE id = 42 ;
id
值不会更改,但如果存在匹配的行,则这些行中的
fo
列的值肯定会更改

要在触发器中检测,我们需要将
OLD.fo
NEW.fo
进行比较。我们还应该考虑从NULL到非NULL的变化,反之亦然

要检测对任意数量列的更改,我们需要检查每一列

  IF  ( OLD.id   <=> NEW.id   )
  AND ( OLD.fee  <=> NEW.fee  )
  AND ( OLD.fi   <=> NEW.fi   )
  AND ( OLD.fo   <=> NEW.fo   )
  AND ( OLD.fum  <=> NEW.fum  ) THEN
     -- the values of these columns (id, fee, fi, fo, fum) is not changed
  ELSE
     -- the value of at least one of the columns id, fee, fi, fo, or fum is changed
  END IF

标准模式是将
id
列作为代理主键,并具有大多数或所有需要的属性:不可空、简单数据类型、唯一、匿名、不可变

更改行的代理项
id
主键值是非常奇怪的用例



更新一行的ID是不常见的,这通常是在更新其他列时保持不变的主键。我认为没有任何内置方法可以告诉您正在修改哪个列。您必须将每个列的
OLD.colname
NEW.colname
进行比较。要对更新的列的名称执行什么操作?如果它正在更新多个专栏呢?为什么你不让你的老师解释他们想用的方法呢?我完全同意@Barmar。。。另外,你现在不是在制作某种自制(按行/按记录)版本吗?@RaymondNijland:是的,你说得对。空安全比较将返回0或1,并且不会返回空值。为了获得真正等价的行为,我们可以执行
((a不为NULL,b不为NULL,a=b)或(a为NULL,b为NULL))
,或者将表达式包装在一个大小写中,或者如果()函数
ab
是为了“支持”并且符合ANSI/ISO SQL,那么
语法没有区别。。是的,我同意同等的写作可以有多种方式。@RaymondNijland:谢谢你的洞察力。我主要使用spaceship操作符进行“相等”比较,当我希望将空值视为与非空值“不相等”,而与另一个空值“相等”时。这样一种方便的简写方法,不需要显式的IS空测试,并且使用ANDIN、ORing和parens来指定操作顺序
a <=> b
( ( a IS NOT NULL AND b IS NOT NULL AND a = b ) OR ( a IS NULL AND b IS NULL ) )