1.问题背景
今天用MySQL创建含流程控制语句函数,遇到总会识别不出数据库中的courses表,courses是存在数据库中,且可以正常使用的,报错如下:
ERROR 1327 (42000): Undeclared variable: courses
– 创建函数:要求输入学生学号sid、课程编号,显示学生姓名、课程名称、成绩是否及格(即成绩>=60)
代码如下:
DELIMITER //
CREATE DEFINER = CURRENT_USER FUNCTION get_student_scores_by_sid(id INT)
RETURNS VARCHAR(300)
DETERMINISTIC
BEGIN
DECLARE name VARCHAR(20);
DECLARE course_name VARCHAR(20);
DECLARE score INT;
SELECT stu.sname INTO name, courses.cname INTO course_name, sc.score INTO score
FROM students AS stu, courses, scores AS sc
WHERE stu.sid = sc.sid AND courses.cid = sc.cid AND stu.sid = id;
IF score >= 60 THEN
RETURN name, '--', course_name, '--', '及格';
ELSEIF score > 0 AND score < 60 THEN
RETURN name, '--', course_name, '--', '不及格';
ELSE
RETURN '找不到该学生或该学生没有选课!';
END IF;
END//
DELIMITER ;
2.原因分析及解决方案
2.1 原因分析
创建函数或者存储过程时,记录集不是允许的类型,因此,不能通过一个参数返回多个行和列,也不能通过一条select语句赋予多个参数值。
2.2 解决方案
将每一个参数分别通过一条select语句去赋值,修改后代码如下:
DROP FUNCTION IF EXISTS get_student_scores_by_id;
DELIMITER //
CREATE DEFINER = CURRENT_USER FUNCTION get_student_scores_by_id(sid INT, cid INT)
RETURNS VARCHAR(300)
DETERMINISTIC
BEGIN
-- 多个变量要分开声明,否则会报错
DECLARE score INT;
DECLARE name VARCHAR(20);
DECLARE course_name VARCHAR(20);
SELECT sc.score INTO score
FROM scores AS sc
WHERE sc.sid = sid AND sc.cid = cid;
-- 注意:多个输出值一定要用多个SELECT来赋值,否则会报错
SELECT sname INTO name FROM students AS stu WHERE stu.sid = sid;
SELECT cname INTO course_name FROM courses AS co WHERE co.cid = cid;
IF score >= 60 THEN
RETURN CONCAT(name, '--', course_name, '--', '及格');
ELSEIF score > 0 AND score < 60 THEN
RETURN CONCAT(name, '--', course_name, '--', '不及格');
ELSE
RETURN '找不到该学生、课程或该学生没有选课!';
END IF;
END//
DELIMITER ;