如何将mysql表中的所有更改记录到第二个?

时间:2011-07-22 09:02:28

标签: mysql triggers

我使用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个字段,我不想在触发器中列出所有字段。

因为当我在表中定义其他字段时,我希望触发器也能复制它们。在创建相应的历史表后,我也可以轻松地将触发器复制到另一个表。

有没有办法复制更新行的所有表字段并将它们插入历史表(具有相同的字段名称)?

4 个答案:

答案 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;