带有字段名称的MySql AF​​TER UPDATE触发器

时间:2011-12-12 20:58:16

标签: mysql triggers

我有两张表格如下。当在“开关”上更新字段时,我需要在“switch_updates”中插入一个条目,其中包括更新字段的名称,旧值和新值。

我已经包含了我已启动的触发器,但我无法弄清楚如何提取已更新字段的名称。

---------------------
|  switches         |
---------------------
|  id               |
|  name (varchar)   |
|  functional (int) |
---------------------


-----------------------------
|  switch_updates           |
-----------------------------
|  id                       |
|  field_name (varchar)     |
|  field_original (varchar) |
|  field_new (varchar)      |
-----------------------------

触发

CREATE TRIGGER SwitchUpdate_Trigger
AFTER UPDATE ON switches
FOR EACH ROW
BEGIN
    INSERT into switch_updates (id, switch_id, field_name, field_original, field_new)
    VALUES 
        (
            null,
            NEW.id, -- switch_id
                  , -- field_name?
            OLD.field_value, --?
            NEW.field_value, --?
        );
END;

3 个答案:

答案 0 :(得分:4)

您无法直接找到已更新的字段名。

你能得到的是行(字段)的值,以及行(字段)的值(OLDNEW)。
您可以比较所有字段的旧值(手动),如果已更改,则应将其插入表中。

可能出现的问题:

  • 您无法确定某个字段是否在查询中,或者是否已使用相同的值“更新”。在这两种情况下,OLD en NEW值都相同
  • 有点劳累

但最终你能得到你想要的东西吗?

答案 1 :(得分:3)

来自create trigger documentation

您可以使用别名OLD和NEW来引用主题表(与触发器关联的表)中的列。 OLD.col_name引用现有行的列更新或删除之前的列。 NEW.col_name指的是要插入的新行的列,或>更新后的现有行

来自一个有趣的blog

在INSERT触发器中,只能使用NEW.col_name,因为没有旧行。在DELETE触发器中,只能使用OLD.col_name,因为没有新行。在UPDATE触发器中,您可以使用OLD.col_name在更新行之前引用行的列,使用NEW.col_name在更新行之后引用行的列。

这意味着您应该能够完成任务。

答案 2 :(得分:2)

我实际上正在处理同样的任务,据我所知,获取更新字段名称的唯一方法是手动检查每个字段,如@Nanne所说。

基本示例:

IF OLD.name <> NEW.name THEN
    INSERT INTO audit_table (`field`, `old_value`, `new_value`)
    VALUES ('name', OLD.name, NEW.name);
END IF;

重复您要跟踪的许多列。如果有人知道更好的方式,我很乐意听到它!