【问题标题】:MySQL - Trigger UPDATE (How values change)MySQL - 触发器更新(值如何变化)
【发布时间】:2016-01-28 19:41:37
【问题描述】:

我的表中有一个触发器“更新后”,但我需要知道如何变化。 我不想这样做:

IF OLD.*column* <> NEW.*column* THEN ...

有人有窍门吗?

【问题讨论】:

  • 这是知道的唯一技巧...

标签: mysql triggers sql-update


【解决方案1】:

没有技巧。如果要检测某列的值发生了变化,需要显式比较OLD.colNEW.col的值。


SQL 的一个怪癖是三值布尔逻辑。对 NULL 值的不等式测试永远不会返回 TRUE。 (在布尔上下文中计算的表达式可以返回以下三个值之一:TRUEFALSENULL

 foo  <> NULL    --> NULL
 NULL <> NULL    --> NULL
 foo  <> bar     --> TRUE

如果您想检测列的值是否已更改,包括对 NULL 值的更改或从 NULL 值更改,则不等式测试不会删除它。

一个技巧是使用空安全比较运算符(宇宙飞船符号 &lt;=&gt;),即使被比较的一个或两个值都是 NULL,它也只会返回 TRUE 或 FALSE,检测差异:

 IF NOT (NEW.col <=> OLD.col) THEN 
    -- value of col was modified
 END IF;

另一个技巧是使用 SQL 语句来帮助生成触发器主体中需要的一些代码。引用 information_schema 数据库中的 columns 表。这是一个简短的示例,但可以扩展为包括其他语句和END IF。可以将此返回的结果粘贴到文本编辑器中,以帮助您构建触发器主体。

SELECT CONCAT(' IF NOT (NEW.`',c.column_name,'` <=> OLD.`',c.column_name,'`) THEN') AS i
  FROM information_schema.columns c
 WHERE c.table_name = 'mytable'
   AND c.table_schema = 'mydatabase'
 ORDER BY c.ordinal_position

返回类似的东西

--------------------------------------------------------------
IF NOT (NEW.`id` <=> OLD.`id`) THEN
IF NOT (NEW.`created` <=> OLD.`created`) THEN
IF NOT (NEW.`display_name` <=> OLD.`display_name`) THEN

如果您有很多列,这将非常有用。

除此之外,实际上并没有任何其他“技巧”。

【讨论】:

    猜你喜欢
    • 2013-01-02
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2020-12-03
    • 1970-01-01
    相关资源
    最近更新 更多