use teachingdb;
/****请在此编写代码,操作完毕之后点击评测******/
DELIMITER $$
/**********Begin**********/
create procedure pro_findname(in word char(10))
Begin
select * from student where sname like concat('%',word,'%');
End $$
/**********End**********/
DELIMITER ;
use teachingdb;
/****请在此编写代码,操作完毕之后点击评测******/
/**********Begin**********/
delimiter ##
create Function count_credit(v_sno char(6))
returns int reads sql data
Begin
declare sums int ;
select sum(credit) into sums from course natural join score where grade >=60 and v_sno=sno;
return sums;
end ##
delimiter ;
/**********End**********/
第3关:存储过程中使用游标
任务描述
本关任务:创建存储过程 ,在存储过程中定义游标计算总学分。
相关知识
为了完成本关任务,你需要掌握:
1.游标的定义;
2.游标的使用。
游标的定义
游标(Cursor)主要用于存储过程和函数中,用于逐行处理查询结果集。
在存储过程或函数中,使用 DECLARE CURSOR 语句来创建游标。
DECLARE cursor_name CURSOR FOR select_statement;
游标的使用
打开游标
OPEN cursor_name;
获取数据
FETCH cursor_name INTO var_name1, var_name2, ...;
关闭游标
CLOSE cursor_name;
举例:通过游标获取users表中的id,name,并输出结果。
DELIMITER //
CREATE PROCEDURE process_users()
BEGIN
-- 声明变量
DECLARE finished INTEGER DEFAULT 0;
DECLARE user_id INT DEFAULT 0;
DECLARE user_name VARCHAR(50) DEFAULT '';
-- 声明游标
DECLARE my_cursor CURSOR FOR SELECT id, name FROM users;
-- 声明结束处理
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
use teachingdb;
/****请在此编写代码,操作完毕之后点击评测******/
/**********Begin**********/
drop procedure if exists p_count_credit;
delimiter ##
create procedure p_count_credit()
begin
declare v_sno varchar(20);
declare v_credit int default 0;
declare stucur cursor for select sno from student;
declare exit handler for not found close stucur ;
open stucur;
while true do
fetch stucur into v_sno;
update student set totalcredit =count_credit(v_sno) where sno=v_sno;
end while;
close stucur;
select *from student;
end ##
delimiter ;
/**********End**********/
use teachingdb;
/****请在此编写代码,操作完毕之后点击评测******/
/**********Begin**********/
delimiter ##
create trigger sum_credit
after insert on score for each row
Begin
if(new.grade>=60) then
update student set totalcredit =totalcredit+(select credit from course where cno=new.cno)
where student.sno=new.sno;
end if;
end ##
delimiter ;
/**********End**********/
use teachingdb;
/****请在此编写代码,操作完毕之后点击评测******/
/**********Begin**********/
delimiter ##
create trigger del_studnet_score
before delete on student for each row
begin
delete from score where sno=old.sno;
end ##
delimiter ;
/**********End**********/
总结:头歌第二关及第三关
常见答题系统工作原理:
问题分析:
在头歌平台的测试过程中,由于他们只进行公开测试用例的验证,部分潜在的逻辑错误可能没有被及时发现。这种情况尤其会影响到 MySQL 相关的习题,因为这些习题通常会涉及到数据库操作的细节,如果没有合适的隐藏测试用例,某些问题可能不会暴露。
例如实验五第二关:
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 自己代码: | 官方代码: |
| use teachingdb; /****请在此编写代码,操作完毕之后点击评测******/ /**********Begin**********/ delimiter ## create Function count_credit(v_sno char(6)) returnsfloat reads sql data Begin declare sumsfloat****; select sum(credit) into sums from course natural join score where grade >=60 and v_sno=sno; return sums; end ## delimiter ; /**********End**********/ | CREATE DEFINER=`root`@`localhost` FUNCTION `count_credit`(stuno CHAR(6)) RETURNS int(11) READS SQL DATA BEGIN DECLARE stucno CHAR(3); DECLARE cred INT DEFAULT 0; DECLARE t_credINT DEFAULT 0; DECLARE done INT DEFAULT FALSE; -- 定义游标,从score表中获取学生所选课程编号 DECLARE stucur CURSOR FOR SELECT cno FROM score WHERE sno = stuno AND grade >= 60; -- 定义处理游标未找到数据时的行为 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; -- 打开游标 OPEN stucur; -- 循环获取课程编号并累加学分 loop_cursor: LOOP FETCH stucur INTO stucno; IF done THEN LEAVE loop_cursor; END IF; -- 获取课程学分 SELECT credit INTO cred FROM course WHERE cno = stucno; -- 累加学分 SET t_cred = t_cred + cred; END LOOP; -- 返回总学分 RETURN t_cred; END |
勘误:因为官方只进行公开实例进行测试,这里都可以进行通过
Mysql习题一般都是继续使用官方的代码进行测试,如果你在第三关依旧写出float的代码 */
复制代码
use teachingdb;
/****请在此编写代码,操作完毕之后点击评测******/
/**********Begin**********/
select sum(credit) from score natural join course where sno='96002';
drop procedure if exists p_count_credit;
delimiter ##
create procedure p_count_credit()
begin
declare v_sno varchar(20);
declare v_credit float default 0;
declare stucur cursor for select sno from student;
declare exit handler for not found close stucur ;
open stucur;
while true do
fetch stucur into v_sno;
select sum(credit) into v_credit from score natural join course where grade>=60 and sno=v_sno;
update student set totalcredit =ifnull(v_credit,0) where sno=v_sno;
end while;
close stucur;
select *from student;
end ##
delimiter ;
/**********End**********/