Как записать все изменения в таблицу mysql во вторую? - PullRequest
4 голосов
/ 22 июля 2011

Я использую этот onChange-триггер, чтобы регистрировать все изменения в моей таблице базы данных mysql "house" в качестве второй таблицы house_history (которая имеет точно такие же поля + идентификатор версии).

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 ]

4 голосов
/ 10 сентября 2012

Это функциональный триггер:

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
);
4 голосов
/ 22 июля 2011

Предполагая, что обе таблицы имеют одинаковые столбцы, что-то вроде

INSERT INTO house_history SELECT * FROM house WHERE hnr = OLD.hnr

Хотя я не уверен, разрешено ли ВЫБРАТЬ из таблицы, при которой активируется триггер.

Но короткие выражения IMO, такие как SELECT * или INSERT INTO без списка столбцов, являются плохой практикой в ​​рабочем коде.

2 голосов
/ 05 октября 2011

Если вас беспокоит необходимость обновления триггера при каждом добавлении столбца, вы можете написать процедуру, которая извлекает список столбцов таблицы из информационной схемы и использует их для ПОДГОТОВКИ оператора CREATE TRIGGER, а затем ВЫПОЛНЯЕТ его .

Однако, поскольку подготовленные операторы в настоящее время невозможны в триггерах, вам все равно придется запускать эту процедуру вручную при каждом изменении таблицы. (Я пытался создать триггер, который динамически обнаруживал изменения отдельных полей в строке таблицы, а затем сохранял каждое изменение как отдельную строку в таблице аудита. Но отсутствие подготовленных операторов мешало мне это делать).

Вероятно, это не стоит усилий, если вы не будете часто добавлять столбцы в таблицу, но если кто-то приложит усилия, пожалуйста, опубликуйте SQL здесь.

1 голос
/ 01 мая 2014

Чтобы добавить к ответу и обратиться к комментарию выше , вы можете добавить дополнительные поля до или после старых значений, при условии, что вы дадите таблице псевдоним, как показано ниже (давая таблицу дома).псевдоним 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...