创建触发器以将旧数据插入新表

时间:2017-04-21 22:15:29

标签: mysql triggers

这是我创建的表格。

USE my_guitar_shop;

DROP TABLE IF EXISTS Products_Audit;

CREATE TABLE Products_Audit ( 
audit_id INT PRIMARY KEY, 
category_id INT REFERENCES categories(category_id), 
product_code VARCHAR ( 10 ) NOT NULL UNIQUE , 
product_name VARCHAR ( 255 ) NOT NULL, 
list_price INT NOT NULL, 
discount_percent INT NOT NULL DEFAULT 0.00 , 
date_updated DATETIME NULL); 

创建名为products_after_update的触发器。此更新后,此触发器应将有关产品的旧数据插入到Products_Audit表中。然后,使用适当的UPDATE语句测试此触发器。

这是我创建的触发器,但数据未显示在Products_Audit表中,它显示全部为null。

USE my_guitar_shop;

DROP TRIGGER IF EXISTS products_after_update;

DELIMITER $$

CREATE TRIGGER products_after_update
BEFORE UPDATE ON products
FOR EACH ROW
BEGIN
  INSERT INTO products_audit (audit_id, product_id, category_id, product_code, 
  product_name, list_price, discount_percent, date_updated)

  SELECT audit_id, products.product_id, products.category_id, products.product_code, 
  products.product_name,products.list_price, products.discount_percent, date_updated

  FROM products JOIN products_audit
  ON products_audit.audit_id = (SELECT audit_id FROM inserted);
END $$

DELIMITER ;

使用INSERT INTO进行编辑

  USE my_guitar_shop;

  DROP TRIGGER IF EXISTS products_after_update;

  DELIMITER $$

  CREATE TRIGGER products_after_update
BEFORE UPDATE ON products
FOR EACH ROW
  BEGIN

  INSERT INTO products_audit (audit_id, product_id, category_id,product_code, 
  product_name, list_price, discount_percent, date_updated)

  VALUES (OLD.audit_id, OLD.product_id, OLD.category_id, OLD.product_code, 
  OLD.product_name, OLD.list_price, OLD.discount_percent, OLD.date_updated)

  DELIMITER ;

2 个答案:

答案 0 :(得分:0)

您的插入过于复杂。正如triggers上的mysql文档所说:

  

在UPDATE触发器中,您可以使用OLD.col_name来引用列   更新前的行和NEW.col_name引用列   更新后的行。

因此,请在插入中使用OLD.column_name格式。另外,我会将audit_id字段设置为自动递增,并将其从插入中删除:

INSERT INTO products_audit (product_id, category_id, product_code, 
product_name, list_price, discount_percent, date_updated)
VALUES (OLD.product_id, OLD.category_id, OLD.product_code, 
OLD.product_name, OLD.list_price, OLD.discount_percent, OLD.date_updated)

答案 1 :(得分:0)

这是我如何做的一个例子:

CREATE OR REPLACE EDITIONABLE TRIGGER E_TABLE_TRG
  before insert or update or delete on e_table 
  for each row 
declare
  l_seq    number;
begin 
  -- Get a unique sequence value to use as the primary key
  select s_seq.nextval
    into l_seq
    from dual;
    
  if inserting then
    :new.date_opened := sysdate;
    :new.last_txn_date := null;
    :new.status := 'A';
  end if;
   
  if inserting then
    insert into e_table_history
    (
     t_seq,
     user_id,
     date_opened,
     last_txn_date,
     status,
     insert_update_delete,
     insert_update_delete_date
    )
    values
    (
     l_seq,
     :new.user_id,
     :new.date_opened,
     :new.last_txn_date,
     :new.status,
     'I',
     sysdate
    );
  elsif updating then 
    insert into e_table_history
    (
     t_seq,
     date_opened,
     last_txn_date,
     status,
     insert_update_delete,
     insert_update_delete_date
    )
    values
    (
     l_seq,
     :new.date_opened,
     :new.last_txn_date,
     :new.status,
     'U',
     sysdate
    );
  else
    insert into e_table_history
    (
     t_seq,
     date_opened,
     last_txn_date,
     status,
     insert_update_delete,
     insert_update_delete_date
    )
    values
    (
     l_seq,
     :old.date_opened,
     :old.last_txn_date,
     :old.status,
     'D',
     sysdate
    );
  end if;
end; 
/

ALTER TRIGGER E_TABLE_TRG ENABLE;
/