目前正在尝试使用通用活动日志表来存储哪些表,字段,值已更改(+必需的主键)
DELIMITER $$
CREATE TRIGGER tr_customers_insert_activity_log AFTER INSERT ON `customers`
FOR EACH ROW
BEGIN
DECLARE curr_column CHAR(255);
DECLARE finished INT DEFAULT false;
DECLARE column_name_cursor CURSOR FOR SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'customers' ORDER BY ordinal_position;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET finished = 1;
OPEN column_name_cursor;
column_loop: LOOP
IF finished THEN
LEAVE column_loop;
END IF;
FETCH column_name_cursor INTO curr_column;
INSERT INTO activity_log(`cid`, `table`, `field`, `value`, `modified_by`, `modified_at`)
VALUES (NEW.cid, 'customers', curr_column, NEW.@curr_column, NEW.modified_by, NEW.modified_at);
END LOOP column_loop;
CLOSE column_name_cursor;
END$$
DELIMITER ;
我遇到的问题是:
INSERT INTO activity_log(`cid`, `table`, `field`, `value`, `modified_by`, `modified_at`)
VALUES (NEW.cid, 'customers', curr_column, NEW.@curr_column, NEW.modified_by, NEW.modified_at);
由于我按名称动态循环遍历每个字段,因此我不知道如何获得NEW。@ curr_column值。如何使用变量的值访问NEW / OLD对象的属性?
澄清语法错误是:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@curr_column, NEW.modified_by, NEW.modified_at); END LOOP column_loop' at line 17
谢谢!
答案 0 :(得分:0)
无法动态解决TRIGGER中的NEW和OLD值。
我们可以使用CASE表达式。但这可能不是你想要的。它不是真的"动态"。我们需要静态地处理我们感兴趣的每个列名称。
CASE curr_column
WHEN 'cid' THEN NEW.cid
WHEN 'foo' THEN NEW.foo
WHEN 'othercol' THEN NEW.othercol
END
同样有问题的是您可能希望在activity_log
表value
列中存储的列的各种数据类型... DATE,INTEGER,DECIMAL,ENUM,VARCHAR,...这些都在进行中需要转换为value
列的单个数据类型。
需要考虑的其他选择:
让触发器保存整行的副本
而不是触发" dynamic",使触发器的创建更加动态...即使用来自information_schema.columns的SELECT来帮助生成触发器定义中所需的内容