將學生表 (t_student) 和成績表 (t_stu_score) 中符合條件的數據 (出生日期 ≥ 1990-03-01 且分數 ≥ 參數閾值) 聚合插入到詳情表 (t_stu_detail)。
CREATE TABLE `t_student` (
`stuNum` INT(11) NOT NULL AUTO_INCREMENT,
`stuName` VARCHAR(20) DEFAULT NULL,
`birthday` DATE DEFAULT NULL,
PRIMARY KEY (`stuNum`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `t_stu_score` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`stuNum` INT(11) DEFAULT NULL,
`score` DECIMAL(6,2) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_t_stu_score` (`stuNum`),
CONSTRAINT `FK_t_stu_score` FOREIGN KEY (`stuNum`) REFERENCES `t_student` (`stuNum`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `t_stu_detail` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`stuName` VARCHAR(20) DEFAULT NULL,
`score` DECIMAL(6,2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DELIMITER $$
CREATE PROCEDURE `proc_AddStuDetail`(IN p_score DECIMAL(6,2))
BEGIN
-- 變量聲明 (必須在開頭)
DECLARE v_stuNum INT;
DECLARE v_stuName VARCHAR(20);
DECLARE v_birthday DATE;
DECLARE v_score DECIMAL(6,2);
DECLARE done INT DEFAULT 0; -- 結束標記,初始化為 0
-- 1. 聲明游標 (SELECT 查詢)
DECLARE stuCursor CURSOR FOR
SELECT stuNum, stuName, birthday FROM t_student;
-- 2. 聲明 NOT FOUND 異常處理器 (游標讀取結束時觸發)
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
-- 3. 打開游標
OPEN stuCursor;
-- 4. 循環讀取
stuLoop: LOOP
-- 取數據到變量
FETCH stuCursor INTO v_stuNum, v_stuName, v_birthday;
-- 判斷是否結束
IF done = 1 THEN
LEAVE stuLoop;
END IF;
-- 業務邏輯
IF v_birthday >= '1990-03-01' THEN
SELECT score INTO v_score FROM t_stu_score WHERE stuNum = v_stuNum;
IF v_score >= p_score THEN
INSERT INTO t_stu_detail VALUES (NULL, v_stuName, v_score);
END IF;
END IF;
END LOOP stuLoop;
-- 5. 關閉游標 (釋放資源,必須執行)
CLOSE stuCursor;
END$$
DELIMITER ;
CALL proc_AddStuDetail(86);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 是游標循環退出的核心機制DECLARE EXIT HANDLER 兜底)INSERT ... SELECT ... JOIN) 或應用層批次處理。此例可優化為單條 SQL:
INSERT INTO t_stu_detail (stuName, score)
SELECT s.stuName, sc.score
FROM t_student s
JOIN t_stu_score sc ON s.stuNum = sc.stuNum
WHERE s.birthday >= '1990-03-01' AND sc.score >= p_score;