我使用onChange-trigger将我的mysql数据库tabel“house”中的所有更改记录为第二个表house_history(具有完全相同的字段+版本ID)。
DELIMITER //
CREATE TRIGGER house_change_trigger BEFORE UPDATE ON house
FOR EACH ROW BEGIN
INSERT INTO house_history
(
hnr,
top,
acc_nr
)
VALUES
(
OLD.hnr,
OLD.top,
OLD.acc_nr
);
END
//
触发器有效,我唯一的问题是,该表有80个字段,我不想在触发器中列出所有字段。
因为当我在表中定义其他字段时,我希望触发器也能复制它们。在创建相应的历史表后,我也可以轻松地将触发器复制到另一个表。
有没有办法复制更新行的所有表字段并将它们插入历史表(具有相同的字段名称)?
答案 0 :(得分:4)
假设两个表具有相同的列,如
INSERT INTO house_history SELECT * FROM house WHERE hnr = OLD.hnr
虽然我不确定是否允许从表格中选择,但触发器会被激活。
但是,SELECT *
或INSERT INTO
等没有列列表的IMO快捷语句在生产代码中是不好的做法。
答案 1 :(得分:4)
这是功能性触发器:
CREATE TRIGGER table1_trigger BEFORE UPDATE ON table1
FOR EACH ROW BEGIN
INSERT INTO table1_versions
SELECT *,null,NOW() FROM table1 WHERE id = OLD.id ;
END`
桌子上的:
CREATE TABLE IF NOT EXISTS `table1` (
`id` int(11) NOT NULL,
.....
);
CREATE TABLE IF NOT EXISTS `table1_versions` (
`id` int(11) NOT NULL,
.....
`idhistory` int(20) NOT NULL auto_increment,
`historydate` datetime default NULL
);
答案 2 :(得分:2)
如果您担心每次添加列时都必须更新触发器,那么您可以编写一个从信息模式中检索表列列表的过程,并使用这些过程来预先创建CREATE TRIGGER语句,然后执行它
但是,由于在触发器中当前无法使用预处理语句,因此每次更改表时仍需要手动运行此过程。 (我试图创建一个触发器,动态检测表行中各个字段的更改,然后将每个更改保存为审计表中的单独行。但是缺少准备好的语句阻止了我这样做。)
除非您经常在表中添加列,否则可能不值得付出努力,但如果有人愿意,请在此处发布SQL。
答案 3 :(得分:1)
要添加答案并解决comment above,您可以在旧值之前或之后添加额外字段,只要您为表格提供如下所示的别名(为房子表提供别名为h并使用h。*而不是*)
DELIMITER //
CREATE TRIGGER `updateHouse` BEFORE UPDATE ON `house`
FOR EACH ROW INSERT INTO house_history
SELECT NULL, h.*, NOW() FROM house h WHERE id = OLD.id
//
DELIMITER ;
使用以下架构
CREATE TABLE `house` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NULL,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB;
CREATE TABLE `house_history` (
`id` INT NOT NULL AUTO_INCREMENT,
`house_id` INT ,
`name` VARCHAR(50) NULL,
`date_changed` DATETIME,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB;