mysql - 用游标触发审计

标签 mysql triggers cursor

我在这里要做的是创建动态触发器:

  1. 从名为 *original_table* 的表中获取列名
  2. 遍历返回的列名。
  3. 如果与列名称关联的旧值和新值之间发生变化,则更新日志表。

我收到此错误消息:[Err] 1054 - “NEW”中的未知列“column_name”

如果我手动输入列名,那么它会起作用,但在那种情况下,这种方法会变成静态的,这取决于人机交互。

触发:

DELIMITER $$

DROP TRIGGER IF EXISTS log_original_table $$

CREATE TRIGGER log_original_table AFTER UPDATE ON original_table
FOR EACH ROW
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE column_name VARCHAR(100);
    DECLARE column_cursor CURSOR FOR SELECT column_name FROM information_schema.columns WHERE table_name = 'original_table';
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN column_cursor;

    read_loop: LOOP
        FETCH column_cursor INTO column_name;

        IF done THEN
            LEAVE read_loop;
        END IF;

        IF (NEW.column_name <> OLD.column_name) THEN
            INSERT INTO original_table_log
                (parent_id, parent_field_name, parent_old_value, parent_new_value, parent_modified_on)
            VALUES
                (NEW.id, column_name, OLD.column_name, NEW.column_name, NOW());
        END IF;

    END LOOP;

  CLOSE column_cursor;

END$$

DELIMITER ;

ORIGINAL_TABLE:

DROP TABLE IF EXISTS `original_table`;
CREATE TABLE `original_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(100) DEFAULT NULL,
  `surname` varchar(100) DEFAULT NULL,
  `username` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

-- ----------------------------
-- Records of original_table
-- ----------------------------
INSERT INTO `original_table` VALUES ('1', 'michael', 'jakson', 'you');
INSERT INTO `original_table` VALUES ('2', 'john', 'travolta', 'me');
INSERT INTO `original_table` VALUES ('3', 'lionel', 'messi', 'her');
INSERT INTO `original_table` VALUES ('4', 'brian', 'adams', 'they');

ORIGINAL_TABLE_LOG:

DROP TABLE IF EXISTS `original_table_log`;
CREATE TABLE `original_table_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) DEFAULT NULL,
  `parent_field_name` varchar(100) DEFAULT NULL,
  `parent_old_value` varchar(100) DEFAULT NULL,
  `parent_new_value` varchar(100) DEFAULT NULL,
  `parent_modified_on` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

最佳答案

您的 original_table 中没有名为 column_name 的列,因此您可以执行任何操作,例如 NEW.COLUMN_NAMEOLD.COLUMN_NAME。例如,你应该做 NEW.First_name

关于mysql - 用游标触发审计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13158538/

相关文章:

MYSQL:重复更新时插入 - 获取当前列值

c# - 将触发器绑定(bind)到父集合中的元素

android - 请帮助!访问 SQLite for android 返回的游标内的数据时出错

java - for 循环而不是 while 循环中的游标功能?

android - onListitemClick 从数据库获取列值

mysql - 在 MySQL 或 R 中对分析数据进行下采样

Mysql 从 LEFT OUTER JOIN 中排除记录

mysql - 选择两个时间范围之间的时间

mysql - 除了使用子查询执行检查约束之外,还有其他选择吗?

MySQL TRIGGER ON INSERT 问题