MySQL - 触发器更新(值如何更改)

时间:2016-01-28 19:41:37

标签: mysql triggers sql-update

我有一个触发器" 更新后"在我的表格中,但我需要知道如何更改。 我不想这样做:

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

有人有诀窍吗?

1 个答案:

答案 0 :(得分:3)

没有技巧。如果要检测列的值是否已更改,则需要明确比较OLD.colNEW.col的值。

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

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

如果要检测列的值是否已更改,包括更改为NULL值还是从NULL值更改,则不等式测试不会将其删除。

一个技巧是使用零安全比较运算符(太空船符号 <=> ),它将仅返回TRUE或FALSE,即使被比较的一个或两个值都是NULL,检测差异:

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

另一个技巧是使用SQL语句来帮助生成触发器主体中需要的一些代码。引用columns数据库中的information_schema表。这是一个简短的示例,但可以扩展为包含其他语句和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

如果你有很多专栏,这会非常有用。

除此之外,还没有任何其他&#34;技巧&#34;。