【问题标题】:Need an abstract trigger in MySQL 5.1 to update an audit log在 MySQL 5.1 中需要一个抽象触发器来更新审计日志
【发布时间】:2011-03-27 02:31:48
【问题描述】:

我需要一种方法来检查表中已更改的任何条目并将条目传递到审核日志中。它需要从表结构中抽象出来。

例如:

CREATE TRIGGER table1_update 
BEFORE UPDATE ON table1 
FOR EACH ROW BEGIN
  DECLARE i_column_name varchar(32);
  DECLARE done INT;
  DECLARE cursor1 CURSOR FOR SELECT column_name FROM information_schema.columns WHERE table_name = 'table1';
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

  OPEN cursor1;
  REPEAT
    FETCH cursor1 INTO i_column_name;
    IF NOT done THEN

      --pass the variable column_name and its old.i_column_name and new.i_column_name values to the audit table

    END IF;
  UNTIL done END REPEAT;
  CLOSE cursor1;
END$$

我们有太多的表需要审核,无法自定义构建每个 INSERT、UPDATE 和 DELETE 触发器。我已经尝试了很多事情,但我认为我不走运。有人有什么想法吗?

【问题讨论】:

    标签: mysql variables triggers audit


    【解决方案1】:

    您不能有抽象触发器,它必须在特定表上定义。最接近的方法是将触发器的代码放入存储过程中,然后每个表的触发器都会调用该过程。

    CREATE PROCEDURE audit_update (IN tablename VARCHAR(64))
    BEGIN
      DECLARE  i_column_name varchar(32);
      DECLARE done INT;
      DECLARE cursor1 CURSOR FOR SELECT column_name FROM information_schema.columns WHERE table_name = tablename;
      DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    
      OPEN cursor1;
      REPEAT
        FETCH cursor1 INTO i_column_name;
        IF NOT done THEN
    
          --pass the variable column_name and its old.i_column_name and new.i_column_name values to the audit table
    
        END IF;
      UNTIL done END REPEAT;
      CLOSE cursor1;
    END
    
    
    CREATE TRIGGER table1_update 
    BEFORE UPDATE ON table1 
    FOR EACH ROW BEGIN
      CALL audit_update('table1');
    END
    

    您应该能够轻松编写脚本,使用 information_schema 或类似的东西为您的所有表创建触发器。

    SELECT CONCAT('CREATE TRIGGER ', table_name, '_update BEFORE UPDATE ON ', table_name, ...) FROM information_schema...
    

    【讨论】:

    • 啊!好主意啊!我们将启动一个构建所有触发器的程序。我将它锁定在我的脑海中,应该有一种我没有考虑过的方法来做到这一点。谢谢!
    • 有谁知道给出的答案是否真的有效?如何从存储过程中的触发器访问 OLD 和 NEW 值??
    • @Dylan 好问题。我很确定您不能将 OLD 和 NEW 传递到程序中,因此它可能不是正确的解决方案。即使您在触发器中包含了所有代码(没有存储过程),我也不确定您是否可以像伪代码那样引用列(NEW.i_column_name 等)
    猜你喜欢
    • 2021-05-20
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 2011-02-16
    • 1970-01-01
    • 2010-10-09
    • 2010-09-29
    相关资源
    最近更新 更多