摘要:在本教程中,您将学习如何创建 MySQL AFTER UPDATE
触发器来记录对表所做的更改。
MySQL AFTER UPDATE
触发器简介
MySQL AFTER UPDATE
触发器在与触发器关联的表上发生更新事件后自动调用。
下面显示了创建 MySQL AFTER UPDATE
触发器的语法:
CREATE TRIGGER trigger_name
AFTER UPDATE
ON table_name FOR EACH ROW
trigger_body
Code language: SQL (Structured Query Language) (sql)
在这个语法中:
首先,在CREATE TRIGGER
子句中指定要创建的触发器的名称。
其次,使用AFTER UPDATE
子句指定调用触发器的时间。
第三,在ON
关键字后指定触发器所属的表的名称。
最后,指定由一个或多个语句组成的触发器主体。
如果触发器主体有多个语句,则需要使用BEGIN END
块。并且,您还需要更改默认分隔符,如以下代码所示:
DELIMITER $$
CREATE TRIGGER trigger_name
AFTER UPDATE
ON table_name FOR EACH ROW
BEGIN
-- statements
END$$
DELIMITER ;
Code language: SQL (Structured Query Language) (sql)
在AFTER UPDATE
触发器中,您可以访问OLD
和NEW
行,但无法更新它们。
MySQL AFTER UPDATE
触发器示例
让我们看一下创建AFTER UPDATE
触发器的示例。
设置样本表
首先,创建一个名为Sales
的表:
DROP TABLE IF EXISTS Sales;
CREATE TABLE Sales (
id INT AUTO_INCREMENT,
product VARCHAR(100) NOT NULL,
quantity INT NOT NULL DEFAULT 0,
fiscalYear SMALLINT NOT NULL,
fiscalMonth TINYINT NOT NULL,
CHECK(fiscalMonth >= 1 AND fiscalMonth <= 12),
CHECK(fiscalYear BETWEEN 2000 and 2050),
CHECK (quantity >=0),
UNIQUE(product, fiscalYear, fiscalMonth),
PRIMARY KEY(id)
);
Code language: SQL (Structured Query Language) (sql)
其次,将示例数据插入Sales
表中:
INSERT INTO Sales(product, quantity, fiscalYear, fiscalMonth)
VALUES
('2001 Ferrari Enzo',140, 2021,1),
('1998 Chrysler Plymouth Prowler', 110,2021,1),
('1913 Ford Model T Speedster', 120,2021,1);
Code language: SQL (Structured Query Language) (sql)
第三,从Sales
表中查询数据以显示其内容:
SELECT * FROM Sales;
Code language: SQL (Structured Query Language) (sql)
最后,创建一个表来存储sales
表中quantit
y 列的更改:
DROP TABLE IF EXISTS SalesChanges;
CREATE TABLE SalesChanges (
id INT AUTO_INCREMENT PRIMARY KEY,
salesId INT,
beforeQuantity INT,
afterQuantity INT,
changedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
Code language: SQL (Structured Query Language) (sql)
创建AFTER UPDATE
触发器示例
以下语句在sales
表上创建AFTER UPDATE
触发器:
DELIMITER $$
CREATE TRIGGER after_sales_update
AFTER UPDATE
ON sales FOR EACH ROW
BEGIN
IF OLD.quantity <> new.quantity THEN
INSERT INTO SalesChanges(salesId,beforeQuantity, afterQuantity)
VALUES(old.id, old.quantity, new.quantity);
END IF;
END$$
DELIMITER ;
Code language: SQL (Structured Query Language) (sql)
在sales
表中的每一行发生更新事件之前,会自动触发此after_sales_update
触发器。
如果将quantity
列中的值更新为新值,触发器将插入一个新行以记录SalesChanges
表中的更改。
让我们详细检查一下触发器:
首先,触发器的名称是CREATE TRIGGER
子句中指定的after_sales_update
:
CREATE TRIGGER after_sales_update
Code language: SQL (Structured Query Language) (sql)
其次,触发事件是:
AFTER UPDATE
Code language: SQL (Structured Query Language) (sql)
第三,触发器关联的表是sales
:
ON Sales FOR EACH ROW
Code language: SQL (Structured Query Language) (sql)
最后,使用触发器主体内的IF-THEN
语句检查新值是否与旧值不同,然后将更改插入SalesChanges
表中:
IF OLD.quantity <> new.quantity THEN
INSERT INTO SalesChanges(salesId,beforeQuantity, afterQuantity)
VALUES(old.id, old.quantity, new.quantity);
END IF;
Code language: SQL (Structured Query Language) (sql)
测试 MySQL AFTER UPDATE
触发器
首先,将id为1的行的数量更新为350:
UPDATE Sales
SET quantity = 350
WHERE id = 1;
Code language: SQL (Structured Query Language) (sql)
after_sales_update
被自动调用。
其次,从SalesChanges
表中查询数据:
SELECT * FROM SalesChanges;
Code language: SQL (Structured Query Language) (sql)
第三,将所有行的销售数量增加到10%:
UPDATE Sales
SET quantity = CAST(quantity * 1.1 AS UNSIGNED);
Code language: SQL (Structured Query Language) (sql)
四、从SalesChanges
表中查询数据:
SELECT * FROM SalesChanges;
Code language: SQL (Structured Query Language) (sql)
由于三行的更新,触发器触发了三次。
在本教程中,您学习了如何创建 MySQL AFTER UPDATE
触发器以在数据更新到表之前验证数据。