摘要:在本教程中,您将学习如何创建 MySQL BEFORE UPDATE
触发器以在数据更新到表之前验证数据。
MySQL BEFORE UPDATE
触发器简介
MySQL BEFORE UPDATE
触发器在与触发器关联的表上发生更新事件之前自动调用。
以下是创建 MySQL BEFORE UPDATE
触发器的语法:
CREATE TRIGGER trigger_name
BEFORE UPDATE
ON table_name FOR EACH ROW
trigger_body
Code language: SQL (Structured Query Language) (sql)
在这个语法中:
首先,在CREATE TRIGGER
关键字后指定要创建的触发器的名称。
其次,使用BEFORE UPDATE
子句指定调用触发器的时间。
第三,在ON
关键字后指定触发器所属的表的名称。
最后,指定包含一个或多个语句的触发器主体。
如果您在trigger_body
中有多个语句,则需要使用BEGIN END
块。此外,您还需要更改默认分隔符,如下所示:
DELIMITER $$
CREATE TRIGGER trigger_name
BEFORE UPDATE
ON table_name FOR EACH ROW
BEGIN
-- statements
END$$
DELIMITER ;
Code language: SQL (Structured Query Language) (sql)
在BEFORE UPDATE
触发器中,您可以更新NEW
值,但不能更新OLD
值。
MySQL BEFORE UPDATE
触发器示例
让我们看一下使用BEFORE 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
('2003 Harley-Davidson Eagle Drag Bike',120, 2020,1),
('1969 Corvair Monza', 150,2020,1),
('1970 Plymouth Hemi Cuda', 200,2020,1);
Code language: SQL (Structured Query Language) (sql)
三、从sales
表查询数据验证插入:
SELECT * FROM sales;
Code language: SQL (Structured Query Language) (sql)
创建BEFORE UPDATE
触发器示例
以下语句在sales
表上创建BEFORE UPDATE
触发器。
DELIMITER $$
CREATE TRIGGER before_sales_update
BEFORE UPDATE
ON sales FOR EACH ROW
BEGIN
DECLARE errorMessage VARCHAR(255);
SET errorMessage = CONCAT('The new quantity ',
NEW.quantity,
' cannot be 3 times greater than the current quantity ',
OLD.quantity);
IF new.quantity > old.quantity * 3 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = errorMessage;
END IF;
END $$
DELIMITER ;
Code language: SQL (Structured Query Language) (sql)
在sales
表中的每一行发生更新事件之前,触发器会自动触发。
如果将quantity
列中的值更新为比当前值大 3 倍的新值,触发器将引发错误并停止更新。
让我们详细检查一下触发器:
首先,触发器的名称是CREATE TRIGGER
子句中指定的before_sales_update
:
CREATE TRIGGER before_sales_update
Code language: SQL (Structured Query Language) (sql)
其次,触发事件是:
BEFORE UPDATE
Code language: SQL (Structured Query Language) (sql)
第三,触发器关联的表是sales
:
ON sales FOR EACH ROW
Code language: SQL (Structured Query Language) (sql)
第四,声明一个变量并将其值设置为错误消息。请注意,在BEFORE TRIGGER
中,您可以通过OLD
和NEW
修饰符访问列的旧值和新值。
DECLARE errorMessage VARCHAR(255);
SET errorMessage = CONCAT('The new quantity ',
NEW.quantity,
' cannot be 3 times greater than the current quantity ',
OLD.quantity);
Code language: SQL (Structured Query Language) (sql)
请注意,我们使用CONCAT()
函数来形成错误消息。
最后,使用IF-THEN
语句检查新值是否比旧值大 3 倍,然后使用SIGNAL
语句引发错误:
IF new.quantity > old.quantity * 3 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = errorMessage;
END IF;
Code language: SQL (Structured Query Language) (sql)
测试 MySQL BEFORE UPDATE
触发器
首先,将id为1的行的数量更新为150:
UPDATE sales
SET quantity = 150
WHERE id = 1;
Code language: SQL (Structured Query Language) (sql)
它之所以有效,是因为新数量不违反规则。
其次,从sales
表中查询数据来验证更新:
SELECT * FROM sales;
Code language: SQL (Structured Query Language) (sql)
第三,将id为1的行的数量更新为500:
UPDATE sales
SET quantity = 500
WHERE id = 1;
Code language: SQL (Structured Query Language) (sql)
MySQL 发出此错误:
Error Code: 1644. The new quantity 500 cannot be 3 times greater than the current quantity 150
Code language: SQL (Structured Query Language) (sql)
在本例中,触发器发现新数量导致违规并引发错误。
最后,使用SHOW ERRORS
显示错误:
SHOW ERRORS;
Code language: SQL (Structured Query Language) (sql)
在本教程中,您学习了如何创建 MySQL BEFORE UPDATE
触发器以在数据更新到表之前验证数据。