【MySQL】8.1 存储程序实例:课程管理

选课功能:“选课”是课程管理系统中的重要环节,选课将学生实体和课程实体有效连接起来。

选课功能的逻辑:
• 同一学生不能重复选同一门课
课程设置有人数上限,选课人数不能超过该上限
• 应提供课程还可供多少人选课的信息
• 如果课程设置有开始选课时间和(或)结束选课时间,在允
许的时间范围内方可选课

“选课”的业务逻辑表达的规则越多,就越值得用存储程序的眼光去看待“选课”,“选课”绝不仅仅是一个具体的“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): 课程选课人数已满
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章