在mysql中创建一个触发器,将一个表中的更改保存到另一个表中

时间:2016-09-01 09:09:04

标签: mysql

我是使用触发器的新手,但我已经阅读了相当多的内容,我认为它是我需要的最佳解决方案。我在mysql中有一个名为employees的表,我想创建一个对员工所做更改的审计跟踪到另一个名为employee_changes的表中。但我只想为employees表中已更改的列创建审计条目。因此,例如,如果用户更改了员工的工资,我希望在employee_changes中创建一行,捕获员工的ID,已更改的列的名称(在本例中为薪水),旧值和新值工资以及用户的日期和名称。当记录保存在前端时,进行更改的用户的名称将始终在employees表的字段(LastUpdatedBy)中更新,因此在触发器触发时,它可以从中获取用户名LastUpdatedBy列。

This PostThis Post的帮助下,我能够提出这段代码:

DELIMITER //
CREATE TRIGGER emp_update
AFTER INSERT
ON employees FOR EACH ROW
BEGIN
DECLARE col_names CURSOR FOR
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'employees'
ORDER BY ordinal_position;
select FOUND_ROWS() into num_rows;
SET i = 1;
the_loop: LOOP
IF i > num_rows THEN
    CLOSE col_names;
    LEAVE the_loop;
END IF;

FETCH col_names 
INTO col_name;    

 IF OLD.col_name <> NEW.col_name THEN
    INSERT INTO employee_changes (EmployeeNumber, FieldName, OldValue, NewValue, ChangeDate, ChangedBy) 
    VALUES(OLD.EmployeeNumber, col_name, OLD.col_name, NEW.col_name, NOW(), NEW.LastUpdatedBy);
 END IF;

SET i = i + 1;  
END LOOP the_loop;

END //
DELIMITER ;

但是当我运行它时,没有任何反应,在INFORMATION_SCHEMA.TRIGGERS中没有创建触发器。因此,当我更新employees表时,我的employee_changes表中没有任何反应。

我觉得我差不多了,但我被卡住了。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

以下行肯定会抛出错误:

IF OLD.col_name <> NEW.col_name THEN

因为col_name不是字段的名称,所以它是一个变量。这将永远不会在MySQL中工作,您必须提供确切的列名称。忘记列名的动态查询,你必须为每列硬编码测试。

同样,在insert语句中,您不能使用OLD.col_nameNEW.col_name公式,您必须逐个显式提供字段名称。如果更改表的结构,则必须更改触发器的代码。

不幸的是,这是MySQL的限制,目前我不知道这个问题的任何解决方案或解决方法。