通過一個完整的「用戶註冊 → 觸發器記錄操作日誌 → 存儲過程批量造數」流程,驗證觸發器與存儲過程的正確性與交互行為。
-- 業務表
CREATE TABLE `airuser` (
`userId` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(128) NOT NULL,
PRIMARY KEY (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 操作日誌表
CREATE TABLE `airuser_record` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) DEFAULT NULL,
`edittime` TIMESTAMP NULL DEFAULT NULL,
`edittype` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TRIGGER IF EXISTS insert_trigger;
DELIMITER //
CREATE TRIGGER insert_trigger
BEFORE INSERT ON airuser
FOR EACH ROW
BEGIN
INSERT INTO airuser_record (username, edittime, edittype)
VALUES (NEW.username, NOW(), 'insert');
END//
DELIMITER ;
-- 查看觸發器
SHOW TRIGGERS;
關鍵點:
- BEFORE INSERT 保證日誌寫入與主表在同一事務,若主表插入回滾,日誌自動回滾。
- NEW.username 訪問即將插入的值。
- DELIMITER // 避免分號衝突。
DROP PROCEDURE IF EXISTS createUsers;
DELIMITER //
CREATE PROCEDURE createUsers(IN cnt INT)
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i < cnt DO
INSERT INTO airuser (username) VALUES (CONCAT('user_', i));
SET i = i + 1;
END WHILE;
END//
DELIMITER ;
SHOW PROCEDURE STATUS WHERE Name = 'createUsers';
-- 調用存儲過程插入 10 條
CALL createUsers(10);
-- 檢查業務表
SELECT * FROM airuser;
-- 檢查日誌表(應同步產生 10 條 insert 記錄)
SELECT * FROM airuser_record;
| airuser | airuser_record |
|---|---|
| userId=1, username='user_0' | id=1, username='user_0', edittype='insert' |
| userId=2, username='user_1' | id=2, username='user_1', edittype='insert' |
| ... | ... |
| userId=10, username='user_9' | id=10, username='user_9', edittype='insert' |
ROLLBACK,確認日誌表無殘留。CALL createUsers(1000),觀察 airuser_record 行數是否精確等於總插入數。DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 記錄錯誤而不中斷主流程。本文提供從 0 到 1 的完整可運行腳本,涵蓋觸發器創建、存儲過程編寫、調用驗證全流程,可直接作為項目模板或教學案例。