MySQL的存储过程中使用游标来接收查询结果集

我们如果要在MySQL的存储过程中遍历一个查询语句的结果集,需要使用到游标cursor(SQL server中可以定义表类型的变量Table,但MySQL中不行,只能用游标)。
在这里插入图片描述

假设我需要从 tb_stu 这张表中查询出所有记录插入到tb_stu_copy1中,等价于insert into tb_stu_copy1 select * from tb_stu;

以下是存储过程的具体sql

CREATE PROCEDURE curdemo () 
BEGIN
	DECLARE stop_flag INT DEFAULT 0;
	DECLARE this_id INT;
	DECLARE this_name VARCHAR ( 100 );
	DECLARE this_sex VARCHAR ( 2 );
	DECLARE	cu CURSOR FOR SELECT * FROM	tb_stu;
	DECLARE	CONTINUE HANDLER FOR SQLSTATE '02000' SET stop_flag = 1;#当fetch游标到了结果即最后一行的时候,设置stop_flag=1
	OPEN cu;#定义完游标之后要打开游标
	FETCH cu INTO this_id, this_name, this_sex;#读取数据到游标
	WHILE
			stop_flag <> 1 DO
			INSERT INTO tb_stu_copy1
		VALUES
			( this_id, this_name, this_sex );
		FETCH cu INTO this_id, this_name, this_sex;
		
	END WHILE;
	CLOSE cu;#关闭游标

END

我们使用游标的公式步骤大概如下:

  1. 定义游标变量 DECLARE 游标变量名 CURSOR FOR 查询语句
  2. 定义一个当游标移动到末尾时执行的操作 DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' 具体操作代码
  3. 打开游标 OPEN 游标变量名
  4. FETCH 关键字存查询结果集中获取数据
  5. 循环遍历(注意MySQL存储过程中不能用for循环)
  6. 关闭游标 CLOSE 游标变量名

这里有一段代码值得注意

DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET stop_flag = 1;

这句话是声明了一个句柄,当 sqlstate 的值为’02000’ 时会执行这个句柄,从而使stop_flag设置为1。而 sqlstate '02000' 是什么意思呢?sqlstate正常状态是返回’00000’的,当发生下述异常之一时,sqlstate就会变成02000

  • SELECT INTO 语句或 INSERT 语句的子查询的结果为空表。
  • 在搜索的 UPDATE 或 DELETE 语句内标识的行数为零。
  • 在 FETCH 语句中引用的游标位置处于结果表最后一行之后。

上述的第三种异常是符合我们的情况的。也就是说,将在遍历完所有结果集之后就会调用sqlstate变成02000。

关于sqlstate更多的状态码,可以查看这篇博客:https://blog.csdn.net/cangyingaoyou/article/details/7402243

这里边有一个关键字 continue ,这个关键字和 exit 关键字相对应的。 continue 语句执行完指定操作后继续循环,而 exit 语句会从最近的 begin...end 语句块中退出。这里指定的操作就是 SET stop_flag = 1 。我们给 stop_flag 设置为1之后continue就会继续循环,然后循环条件判断发现stop_flag <>1 不满足,于是while循环就结束了

注意:句柄要定义在游标之后, 不然会报 1338 - Cursor declaration after handler declaration 错误。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是在MySQL创建存储过程使用游标在stuDB数据库根据学生姓名查询学生成绩,并统计该学生所有成绩及格数和不及格数的代码: ```mysql DELIMITER $$ CREATE PROCEDURE `get_student_scores`(IN name VARCHAR(50), OUT pass_count INT, OUT fail_count INT) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE score FLOAT; DECLARE cur CURSOR FOR SELECT score FROM scores WHERE student_name = name; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; SET pass_count = 0; SET fail_count = 0; OPEN cur; read_loop: LOOP FETCH cur INTO score; IF done THEN LEAVE read_loop; END IF; IF score >= 60 THEN SET pass_count = pass_count + 1; ELSE SET fail_count = fail_count + 1; END IF; END LOOP; CLOSE cur; END$$ DELIMITER ; ``` 该存储过程接收一个参数name,表示要查询成绩的学生姓名。同时,它还定义了两个输出参数pass_count和fail_count,分别表示及格数和不及格数。 在存储过程,首先声明了一个游标cur,用于查询指定学生的所有成绩。然后,通过循环遍历游标结果,统计该学生的及格数和不及格数。最后,关闭游标并返回结果。 使用存储过程的示例代码如下: ```mysql SET @pass_count = 0; SET @fail_count = 0; CALL get_student_scores('张三', @pass_count, @fail_count); SELECT @pass_count AS pass_count, @fail_count AS fail_count; ``` 该代码将查询姓名为“张三”的学生的所有成绩,并统计该学生的及格数和不及格数,最终输出结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值