選課功能:“選課”是課程管理系統中的重要環節,選課將學生實體和課程實體有效連接起來。
選課功能的邏輯:
• 同一學生不能重複選同一門課
• 課程設置有人數上限,選課人數不能超過該上限
• 應提供課程還可供多少人選課的信息
• 如果課程設置有開始選課時間和(或)結束選課時間,在允
許的時間範圍內方可選課
“選課”的業務邏輯表達的規則越多,就越值得用存儲程序的眼光去看待“選課”,“選課”絕不僅僅是一個具體的“choose”表。以下定義一組存儲程序來服務於課程管理。
存儲程序實例
存儲函數get_available_count
存儲函數get_available_count,返回指定課程的可選課人數。
• 主表course表的Capacity字段值減去子表choose表中關聯記錄數
CREATE FUNCTION get_available_count(c_id CHAR(4))
RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
COMMENT '課程的可選課人數'
RETURN (
SELECT Capacity - (SELECT COUNT(*) FROM choose
WHERE choose.Course_id = course.Course_id)
FROM course WHERE course_id=c_id
);
調用get_available_count,查詢包含可選課人數的課程列表
mysql> SELECT Course_id, Course_Name, Capacity,
-> get_available_count(Course_id) AS Available
-> FROM course
-> ORDER BY Available;
結果:
+-----------+----------------+----------+-----------+
| Course_id | Course_Name | Capacity | Available |
+-----------+----------------+----------+-----------+
| 1003 | 計算機基礎 | 60 | 35 |
| 1004 | 數據庫應用 | 60 | 40 |
| 1001 | 高等數學 | 60 | 40 |
| 1006 | 藝術概論 | 60 | 40 |
| 1010 | 大學英語(二) | 60 | 45 |
存儲過程choose_course
存儲過程choose_course,在數據庫內記錄學生和課程的關聯
• 存儲過程需要學號和課程號兩個輸入參數
• 存儲過程應該用一個輸出參數說明執行結果是成功還是失敗
CREATE PROCEDURE choose_course(IN sid CHAR(12), IN cid CHAR(4),OUT status INT)
NOT DETERMINISTIC MODIFIES SQL DATA COMMENT '學生選課'
BEGIN
DECLARE begin_time, end_time DATETIME;
DECLARE dt_now DATETIME DEFAULT NOW();
// 定義局部變量
SELECT course.Begin_choose_time, course.End_choose_time
INTO begin_time, end_time FROM course where Course_id=cid;
// 返回結果集
-- 利用IF語句,用status在不同情況下返回不同的狀態結果,向choose表插入記錄
END
如果學生尚未選擇某課程,並且課程容量允許,當前時間在選課時間範圍內,就插入選課記錄,否則報告相應的錯誤。
以下是詳細的IF語句。
IF (SELECT COUNT(*) FROM choose WHERE Student_id=sid AND Course_id=cid) = 1 THEN
SET status = -1;
ELSEIF get_available_count(cid) = 0 THEN
SET status = -2;
ELSEIF begin_time IS NOT NULL AND dt_now < begin_time OR
end_time IS NOT NULL AND dt_now > end_time THEN
SET status = -3;
ELSE
INSERT INTO choose VALUES(NULL, sid, cid, dt_now, NULL);
SET status = 0;
END IF;
調用choose_course,完成選課業務操作
• 數據庫中相關記錄的情況不同,choose_course執行的結果可能不同。
SET @STATUS = 0;
CALL choose_course('201810201103', '1003', @status);
SELECT @STATUS;
解釋:
@STATUS有四種狀態,-1表示選課重複,-2表示課程容量已滿,-3表示未在選課時間內,0表示選課成功
觸發器choose_course_constraint
觸發器choose_course_constraint,實現選課人數的約束
• 在choose表上創建BEFORE INSERT的觸發器,如果新加記錄的課程號所對應的課程可供選課人數已經爲零,則報告錯誤。
CREATE TRIGGER choose_course_constraint
BEFORE INSERT
ON choose FOR EACH ROW
BEGIN
IF get_available_count(New.Course_id) = 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '課程選課人數已滿';
END IF;
END
mysql> INSERT INTO choose VALUES(NULL,'201810201103','1003', NOW(), NULL);
ERROR 1644 (45000): 課程選課人數已滿