游标 cursor 就像一个数组遍历,感觉游标还挺好用的。
1.定义游标:
DECLARE cursor_name CURSOR FOR select_statement;
在定义游标时从select语句中获取到的信息都暂时存到了游标名里面,在下面可以使用 “fetch 游标名 into 变量名” 将select获取到的信息存入变量中,然后利用其他语言对这些变量进行其他操作。
2.打开游标:
声明游标之后,要想从游标中提取数据,必须首先打开游标。在 MySQL 中,打开游标通过 OPEN 关键字来实现,其语法格式如下:
OPEN cursor_name;
3.使用游标:
游标顺利打开后,可以使用 FETCH...INTO 语句来读取数据,其语法形式如下:
FETCH cursor_name INTO var_name [,var_name]...
上述语句中,将游标 cursor_name 中 SELECT 语句的执行结果保存到变量参数 var_name 中。变量参数 var_name 必须在游标使用之前定义。使用游标就和高级语言中的数组遍历差不多,当第一次使用游标时,此时游标指向结果集的第一条记录。
MySQL 的游标是只读的,也就是说,你只能顺序地从开始往后读取结果集,不能从后往前,也不能直接跳到中间的记录。
4.关闭游标
游标使用完毕后,要及时关闭,在 MySQL 中,使用 CLOSE 关键字关闭游标,其语法格式如下:CLOSE cursor_name;
CLOSE 释放游标使用的所有内部内存和资源,因此每个游标不再需要时都应该关闭。
在一个游标关闭后,如果没有重新打开,则不能使用它。但是,使用声明过的游标不需要再次声明,用 OPEN 语句打开它就可以了。
如果你不明确关闭游标,MySQL 将会在到达 END 语句时自动关闭它。游标关闭之后,不能使用 FETCH 来使用该游标。
所以可以利用游标将你需要的数据信息存入,进行一条一条的处理,而且利用游标处理是按select出来的数据顺序从前往后挨个处理的,在做题时,你可以设置一个循环,设置一下循环条件,再进行游标处理,在循环体结束前改变循环条件变量值。例如mysql实验4.3 while循环
While 循环
While 循环语法
- 语法:
- [循环语句标签:] while循环条件
- do
- 循环语句;
- #可包含leave[循环语句标签]语句和iterate语句
- end while [循环语句标签] ;
功能: 当循环条件成立时,一遍又一遍反复执行循环体, 直到条件不成立为止。
While 循环执行流程:
While 执行流程:① 求解“循环条件”:若结果为 False,转第 ③步;若为 True 转第 ② 步; ② 执行 1 遍循环语句,转第 ① 步。 ③ 结束循环,执行紧邻的后续语句。
需要注意的是:
•While 之前的可选项“[循环语句标签:]”和 End while 后的“[循环语句标签]”必须一致。
•end while 后必须以“;”结束。
•“循环语句;”可以是 1 条或多条 MySQL 语句,可包含 leave 和 iterate 语句。
•Iterate 语句作用:循环是很多遍的反复执行,iterate 语句仅仅提前结束一遍的执行。此时还在循环中,若循环条件还成立,则会再次从头执行循环体,直到条件不成立时循环才正常结束。
•leave 语句用于在循环条件仍然成立时就跳出循环外,提前终结本循环。
【例】素数是只能被1和它自身整除的正整数。 请设计函数 IsPrime ,判断给定正整数 n 是不是素数。
•题目解析:若 n 是素数,则比 n 小的这些正整数 i:2,3,4,...,n-1 都不可能整除 n。反之,若发现其中有任意1个i能整除 n,则 n 一定不是素数。因此可以设计一个测试循环:
•循环条件是:测试 n 的正整数i要大于或等于 2,而且要小于 n;
•循环体则完成一次具体的测试,也就是每一遍循环都分 2 步走:
•第 1 步:先用i测试,若能整除n则提前得出结论,用 Leave 终结测试循环;
•第 2 步:改i为下一个正整数,以备下一次循环时用来测试n。
- create function IsPrime( n int ) returns int
- begin
- declare i int default 2 ; #i代表从2开始,直到n-1中的一个正整数
- declare yn int default 1 ; #先假定yn为1,代表n是素数
- test: while i < n do
- if n % i = 0 then #i能整除n,反证n不是素数
- set yn = 0 ; #改yn为0,表示n不是素数
- leave test ; #结论已提前锁定,不再测试小于n的其它数
- end if ;
- set i = i+1 ; #准备下一个用来测试n的正整数
- end while test ;
- return yn ;
- end ; #select IsPrime( 2 ), IsPrime( 3 ), IsPrime( 9 ) ;
编程要求
根据提示,在右侧编辑器补充代码,使用 While 语句实现以下需求:
- 获取学号为参数值所对应的学生已经获得的总学分。
注意:数据库结构如下
/****请在此编写代码,操作完毕之后点击评测******/
#获取学号为参数值所对应的学生已经获得的总学分
use course;
set names utf8;
drop procedure if exists sumCredits;
#更改命令结束标记为$$
delimiter $$
create procedure sumCredits( stu_id char(12) ) #创建存储过程
begin #创建sumCredits过程
#定义6个局部变量
declare s, m, n, x, y int;
declare msg char(30) charset utf8;
#定义1个游标rs
declare rs cursor for
select a.score, b.credit
from choose a, course b
where a.course_id=b.course_id and student_id=stu_id ;
#rs用于逐一检查指定学号学生的成绩和学分
#查询结果集总记录数,存入变量n
select count(*) into n
from choose a, course b
where a.course_id=b.course_id and student_id=stu_id ;
if n < 1 then #查不到选课记录时退出循环
set msg = concat('无此学生 ', convert(stu_id using utf8), ' 或 该生未选修课程。' );
select msg as `查询结果是:`;
else
set s = 0, m = 1; #设置局部变量s和m的初值
open rs; #打开游标rs
#请用While语句实现相应功能。
/**********Begin**********/
test:while m<=n do #开始while循环,游标一共存储了n条数据,因为游标从第一条数据开始处理,处理完一条再处理下一条,所以用m=1作为循环条件,当m加到比n大时,游标中的信息也没有了,循环也正好结束了。
fetch rs into x,y; #将游标中的信息拿出来赋给x,y,定义游标时select语句将有选课的学生的score和credit信息存到了rs中,所以在使用游标时要将执行结果保存到两个变量中。
if x>=60 then #判断 score及格才能加相应的学分,否则不加。
set s=s+y; #看到下面输出是用s代表总学分,所以将credit加到s上。
end if; #if和end if要成对使用。
set m=m+1; #循环条件,要取下一条游标中的信息了,为了让循环有止境的循环,要将循环条件改变,用m去和n比较的,m初值为1,所以m+1。
end while; #while和end while 成对使用。
/**********End**********/
close rs; #关闭游标
#显示结果
select student_id 学生, a.course_id 课程号, score 成绩, credit 学分
from choose a left join course b
on a.course_id=b.course_id
where student_id=stu_id;
select stu_id as 学生, s as `已经获得的总学分`;
end if;
end $$
# 过程定义结束
# 恢复语句结束标志
delimiter ;
游标知识点参考的是:MySQL游标(Cursor)的定义及使用 (biancheng.net)