Question

I have a mysql table that whenever there is an add, modify/update, or delete, I want to take the row and add it to an "archive" table (before it is updated or deleted). This is for a historical archive (i.e. what happened). Is there a way to do this in the database layer "automatically"? Is there a better way...

Was it helpful?

Solution

You'll need a group of triggers that cover all operations (insert, update, delete).

Let's say you have a table

CREATE TABLE table1
(
  table1_id int not null auto_increment primary key, 
  column1 varchar(32)
);

and you created the following history table for it

CREATE TABLE table1_history
(
  history_id int not null auto_increment primary key, 
  dt datetime not null, 
  operation varchar(6) not null, 
  table1_id int not null, 
  column1 varchar(32) not null
);

Now your triggers might look something like

CREATE TRIGGER tg_ai_table1
AFTER INSERT ON table1
FOR EACH ROW
  INSERT INTO table1_history (dt, operation, table1_id, column1)
  VALUES(NOW(), 'insert', NEW.table1_id, NEW.column1);

CREATE TRIGGER tg_au_table1
AFTER UPDATE ON table1
FOR EACH ROW
  INSERT INTO table1_history (dt, operation, table1_id, column1)
  VALUES(NOW(), 'update', NEW.table1_id, NEW.column1);

CREATE TRIGGER tg_bd_table1
BEFORE DELETE ON table1
FOR EACH ROW
  INSERT INTO table1_history (dt, operation, table1_id, column1)
  VALUES(NOW(), 'delete', OLD.table1_id, OLD.column1);

If we issue the following DML statements against table1

INSERT INTO table1 (column1) VALUES ('value1'), ('value2');
UPDATE table1 SET column1 = 'value11' WHERE table1_id = 1;
DELETE FROM table1 WHERE table1_id = 2;

table1 will contain

| TABLE1_ID | COLUMN1 |
|-----------|---------|
|         1 | value11 |

table1_history will contain

| HISTORY_ID |                             DT | OPERATION | TABLE1_ID | COLUMN1 |
|------------|--------------------------------|-----------|-----------|---------|
|          1 | January, 04 2014 06:31:15+0000 |    insert |         1 |  value1 |
|          2 | January, 04 2014 06:31:15+0000 |    insert |         2 |  value2 |
|          3 | January, 04 2014 06:31:15+0000 |    update |         1 | value11 |
|          4 | January, 04 2014 06:31:15+0000 |    delete |         2 |  value2 |

Here is SQLFiddle demo

OTHER TIPS

Try to use Trigger

eg:

DROP TRIGGER auditlog

CREATE TRIGGER auditlog BEFORE UPDATE ON frequencies

FOR EACH ROW BEGIN  

INSERT INTO frequencies_audit select * from frequencies where freqId = NEW.freqId;

END;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top