实验4.3 while循环 (游标)

游标 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 循环语法

  1. 语法:
  2. [循环语句标签:] while循环条件
  1. do
  1. 循环语句;
  1. #可包含leave[循环语句标签]语句和iterate语句
  1. 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。

  1. create function IsPrime( n int ) returns int
  1. begin
  1.     declare i int default 2 ; #i代表从2开始,直到n-1中的一个正整数
  2.     declare yn int default 1 ; #先假定yn1,代表n是素数
  3.     test: while i < n do
  4.     if n % i = 0 then #i能整除n,反证n不是素数
  5.     set yn = 0 ; #yn0,表示n不是素数
  6.     leave test ; #结论已提前锁定,不再测试小于n的其它数
  7.     end if ;
  8.     set i = i+1 ; #准备下一个用来测试n的正整数
  9.     end while test ;
  10.     return yn ;
  11.     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;    #设置局部变量sm的初值

        open  rs;        #打开游标rs

    #请用While语句实现相应功能。

   /**********Begin**********/

   

  test:while m<=n do   #开始while循环,游标一共存储了n条数据,因为游标从第一条数据开始处理,处理完一条再处理下一条,所以用m=1作为循环条件,当m加到比n大时,游标中的信息也没有了,循环也正好结束了。

  fetch rs into x,y;   #将游标中的信息拿出来赋给xy,定义游标时select语句将有选课的学生的scorecredit信息存到了rs中,所以在使用游标时要将执行结果保存到两个变量中。

  if x>=60 then        #判断 score及格才能加相应的学分,否则不加。

  set s=s+y;           #看到下面输出是用s代表总学分,所以将credit加到s上。

  end if;              #ifend if要成对使用。

  set m=m+1;           #循环条件,要取下一条游标中的信息了,为了让循环有止境的循环,要将循环条件改变,用m去和n比较的,m初值为1,所以m+1

  end while;           #whileend 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)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值