假设我有两个名为 widgetCustomer
和 widgetSale
的表。在 widgetSale
中插入时,我想向 widgetSale
行添加时间戳,并将销售 id
作为 last_order_id
添加到 widgetCustomer
表中。
我知道使用 AFTER INSERT ON
会导致尝试更新 NEW
行时出错,因此我们需要使用 BEFORE INSERT ON
子句。这带来了一个新问题,即 AUTO_INCREMENT
尚未生成待售 ID,因此 last_order_id 将全部为零。有一种方法可以在 MySQL/MariaDB TRIGGER 执行此操作,但在我的系统上似乎失败了(即,最后一个订单 ID 仍然为零)。
作为一种解决方法,我使用了两种不同的触发器,一种是在插入之前,一种是在插入之后。虽然它确实有效,但我很想知道上述方法是否存在可能的缺陷,以及是否有更好的方法(在性能和数据完整性方面)。
我的代码如下:
DROP TABLE IF EXISTS widgetSale;
DROP TABLE IF EXISTS widgetCustomer;
DROP TABLE IF EXISTS widgetLog;
CREATE TABLE widgetCustomer ( id integer primary key AUTO_INCREMENT, name TEXT, last_order_id INT, stamp TEXT );
CREATE TABLE widgetSale ( id integer primary key AUTO_INCREMENT, item_id INT, customer_id INTEGER, quan INT, price INT, stamp TEXT );
CREATE TABLE widgetLog ( id integer primary key AUTO_INCREMENT, stamp TEXT, event TEXT, username TEXT, tablename TEXT, table_id INT);
INSERT INTO widgetCustomer (name) VALUES ('Bob');
INSERT INTO widgetCustomer (name) VALUES ('Sally');
INSERT INTO widgetCustomer (name) VALUES ('Fred');
SELECT * FROM widgetCustomer;
CREATE TRIGGER stampSale BEFORE INSERT ON widgetSale
FOR EACH ROW BEGIN
SET NEW.stamp = CURRENT_TIMESTAMP();
END
CREATE TRIGGER stampOnRest AFTER INSERT ON widgetSale
FOR EACH ROW BEGIN
UPDATE widgetCustomer SET last_order_id = NEW.id, stamp = CURRENT_TIMESTAMP()
WHERE widgetCustomer.id = NEW.customer_id;
INSERT INTO widgetLog (stamp, event, username, tablename, table_id)
VALUES (CURRENT_TIMESTAMP(), 'INSERT', 'TRIGGER', 'widgetSale', NEW.id);
END
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (1, 3, 5, 1995);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (2, 2, 3, 1495);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (3, 1, 1, 2995);
SELECT * FROM widgetSale;
SELECT * FROM widgetCustomer;
SELECT * FROM widgetLog;
我在 Archlinux 上使用 mariadb 10.6.*。