2010-08-09 56 views
2

我需要一种方法来检查并将条目传递到审计日志中,以更改已更改的表中的任何条目。它需要从表格结构中抽象出来。需要MySQL 5.1中的抽象触发器来更新审计日志

例如:

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触发太多的表。我尝试了很多东西,我想我运气不好。有人有主意吗?

回答

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... 
+0

啊!好主意啊!我们将启动一个将构建所有触发器的过程。我把它锁在我的脑海里,应该有办法做到这一点,我没有考虑到这种做法。谢谢! – 2010-08-10 03:53:04

+0

有谁知道给出的答案是否真的有效?如何从存储过程中的触发器访问OLD和NEW值? – Dylan 2011-01-04 01:05:57

+0

@Dylan好问题。我很确定你不能将旧的和旧的传入程序,所以它可能不是正确的解决方案。即使你把所有的代码都包含在触发器中(没有存储过程),我不确定你可以像伪代码那样引用列(NEW.i_column_name等) – nathan 2011-01-04 04:37:33