想在UPDATE之后写一个触发器

时间:2017-02-17 08:12:13

标签: mysql triggers

我已经写了一个触发器,它会记录每次数据更新,并会记录previous_value, new_value, field_name等等。但问题是我的表中有 77个字段。因此,为每个字段编写IF ENDIF很困难,所以我想知道是否可以使用循环编写?

已经在dba.stackexchange.com上询问但是还没有得到任何富有成效的答案,请在下面链接::

Link

到目前为止我已尝试过::

BEGIN

IF(OLD.company_name != NEW.company_name) THEN
 INSERT INTO elm_activity_log (user_id, action_on, action, action_col, action_old_value, action_new_value, action_at, action_on_id) VALUES (NEW.updated_by, "company", "update", "company_name", OLD.company_name, NEW.company_name, CURRENT_TIMESTAMP(), NEW.company_id);
END IF;
IF(OLD.company_first_name != NEW.company_first_name) THEN
 INSERT INTO elm_activity_log (user_id, action_on, action, action_col, action_old_value, action_new_value, action_at, action_on_id) VALUES (NEW.updated_by, "company", "update", "company_first_name", OLD.company_first_name, NEW.company_first_name, CURRENT_TIMESTAMP(), NEW.company_id);
END IF;

END

请帮助,或任何建议将非常有帮助。

提前致谢。

1 个答案:

答案 0 :(得分:1)

您不能自动执行此操作,但我理解您的观点。只要你足够聪明,懒惰实际上是计算机科学的一种品质。

我通常使用“自动编程”克服这类问题:制作生成代码的代码。

您有2个选项来生成SQL语句:

1. Pure SQL 
2. Programming language

以下是使用SQL的解决方案的开始:

SELECT 
    CONCAT
    (
        'IF(OLD.company_name != NEW.company_name) THEN \n
         INSERT INTO elm_activity_log (user_id, action_on, action, action_col, action_old_value, action_new_value, action_at, action_on_id) VALUES (NEW.updated_by, "company", "update", "', T.column_name,'", OLD.', T.column_name, ', NEW.', T.column_name,', CURRENT_TIMESTAMP(), NEW.company_id); \n
        END IF; \n
        \n
        '
    ) as SQLstatement

FROM
(
    SELECT column_name
    FROM information_schema.columns
    WHERE column_name NOT IN ('id') 
      AND table_name = 'your_table'  
      AND table_schema = 'database_name'
) T

它可能会直接工作,可能需要重写一点点。你还没有提供你的表DLL,所以我很难测试它是否有效。

这个想法是为每个列名生成一行,包含该列触发器部分的SQL语句。然后,您可以将此查询的结果导出到文本文件中,等等。

在嵌套查询中进行相应调整:table_name,table_schema和要从日志记录中排除的列(我设置'id')。

请注意,在SELECT CONCAT中,我添加了一些/n,它应该以输出中的回车结束