MySQL之游标

  • 游标的概念

    • 游标可以遍历返回的多行结果,每次拿到一整行数据

    • 在存储过程和函数中可以使用游标对结果集进行循环的处理

    • 简单来说游标就类似于集合的迭代器遍历

    • MySQL中的游标只能用在存储过程和函数中

  • 游标的语法
    • 创建游标

      -- 标准语法
      DECLARE 游标名称 CURSOR FOR 查询sql语句;

    •  打开游标

      -- 标准语法
      OPEN 游标名称;

    • 使用游标获取数据

      -- 标准语法
      FETCH 游标名称 INTO 变量名1,变量名2,...;

    • 关闭游标

      -- 标准语法
      CLOSE 游标名称;

    • 游标的基本使用
      -- 创建stu_score表
      CREATE TABLE stu_score(
      	id INT PRIMARY KEY AUTO_INCREMENT,
      	score INT
      );
      
      /*
      	将student表中所有的成绩保存到stu_score表中
      */
      DELIMITER $
      
      CREATE PROCEDURE pro_test11()
      BEGIN
      	-- 定义成绩变量
      	DECLARE s_score INT;
      	-- 创建游标,查询所有学生成绩数据
      	DECLARE stu_result CURSOR FOR SELECT score FROM student;
      	
      	-- 开启游标
      	OPEN stu_result;
      	
      	-- 使用游标,遍历结果,拿到第1行数据
      	FETCH stu_result INTO s_score;
      	-- 将数据保存到stu_score表中
      	INSERT INTO stu_score VALUES (NULL,s_score);
      	
      	-- 使用游标,遍历结果,拿到第2行数据
      	FETCH stu_result INTO s_score;
      	-- 将数据保存到stu_score表中
      	INSERT INTO stu_score VALUES (NULL,s_score);
      	
      	-- 使用游标,遍历结果,拿到第3行数据
      	FETCH stu_result INTO s_score;
      	-- 将数据保存到stu_score表中
      	INSERT INTO stu_score VALUES (NULL,s_score);
      	
      	-- 使用游标,遍历结果,拿到第4行数据
      	FETCH stu_result INTO s_score;
      	-- 将数据保存到stu_score表中
      	INSERT INTO stu_score VALUES (NULL,s_score);
      	
      	-- 关闭游标
      	CLOSE stu_result;
      END$
      
      DELIMITER ;
      
      -- 调用pro_test11存储过程
      CALL pro_test11();
      
      -- 查询stu_score表
      SELECT * FROM stu_score;
      
      
      -- ===========================================================
      /*
      	出现的问题:
      		student表中一共有4条数据,我们在游标遍历了4次,没有问题!
      		但是在游标中多遍历几次呢?就会出现问题
      */
      DELIMITER $
      
      CREATE PROCEDURE pro_test11()
      BEGIN
      	-- 定义成绩变量
      	DECLARE s_score INT;
      	-- 创建游标,查询所有学生成绩数据
      	DECLARE stu_result CURSOR FOR SELECT score FROM student;
      	
      	-- 开启游标
      	OPEN stu_result;
      	
      	-- 使用游标,遍历结果,拿到第1行数据
      	FETCH stu_result INTO s_score;
      	-- 将数据保存到stu_score表中
      	INSERT INTO stu_score VALUES (NULL,s_score);
      	
      	-- 使用游标,遍历结果,拿到第2行数据
      	FETCH stu_result INTO s_score;
      	-- 将数据保存到stu_score表中
      	INSERT INTO stu_score VALUES (NULL,s_score);
      	
      	-- 使用游标,遍历结果,拿到第3行数据
      	FETCH stu_result INTO s_score;
      	-- 将数据保存到stu_score表中
      	INSERT INTO stu_score VALUES (NULL,s_score);
      	
      	-- 使用游标,遍历结果,拿到第4行数据
      	FETCH stu_result INTO s_score;
      	-- 将数据保存到stu_score表中
      	INSERT INTO stu_score VALUES (NULL,s_score);
      	
      	-- 使用游标,遍历结果,拿到第5行数据
      	FETCH stu_result INTO s_score;
      	-- 将数据保存到stu_score表中
      	INSERT INTO stu_score VALUES (NULL,s_score);
      	
      	-- 关闭游标
      	CLOSE stu_result;
      END$
      
      DELIMITER ;
      
      -- 调用pro_test11存储过程
      CALL pro_test11();
      
      -- 查询stu_score表,虽然数据正确,但是在执行存储过程时会报错
      SELECT * FROM stu_score;

    • 游标的优化使用(配合循环使用)

      /*
          当游标结束后,会触发游标结束事件。我们可以通过这一特性来完成循环操作
          加标记思想:
              1.定义一个变量,默认值为0(意味着有数据)
              2.当游标结束后,将变量值改为1(意味着没有数据了)
      */
      -- 1.定义一个变量,默认值为0(意味着有数据)
      DECLARE flag INT DEFAULT 0;
      -- 2.当游标结束后,将变量值改为1(意味着没有数据了)
      DECLARE EXIT HANDLER FOR NOT FOUND SET flag = 1;

      /*
      	将student表中所有的成绩保存到stu_score表中
      */
      DELIMITER $
      
      CREATE PROCEDURE pro_test12()
      BEGIN
      	-- 定义成绩变量
      	DECLARE s_score INT;
      	-- 定义标记变量
      	DECLARE flag INT DEFAULT 0;
      	-- 创建游标,查询所有学生成绩数据
      	DECLARE stu_result CURSOR FOR SELECT score FROM student;
      	-- 游标结束后,将标记变量改为1
      	DECLARE EXIT HANDLER FOR NOT FOUND SET flag = 1;
      	
      	-- 开启游标
      	OPEN stu_result;
      	
      	-- 循环使用游标
      	REPEAT
      		-- 使用游标,遍历结果,拿到数据
      		FETCH stu_result INTO s_score;
      		-- 将数据保存到stu_score表中
      		INSERT INTO stu_score VALUES (NULL,s_score);
      	UNTIL flag=1
      	END REPEAT;
      	
      	-- 关闭游标
      	CLOSE stu_result;
      END$
      
      DELIMITER ;
      
      -- 调用pro_test12存储过程
      CALL pro_test12();
      
      -- 查询stu_score表
      SELECT * FROM stu_score;
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悠然予夏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值