• GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。

内容提纲

一、测试环境搭建

二、执行过程解析

三、注意事项

一、测试环境搭建

首先创建一张表,并插入几行数据字段:

CREATE TABLE t (s1 INT, s2 char(100),PRIMARY KEY (s1));
INSERT INTO t values(1,'aaa');
INSERT INTO t values(2,'bbb');
INSERT INTO t values(3,'ccc');

接着创建存储过程,这里的v_total用于判断数据行数。

因为MySQL游标获取完后,最后一行没有退出机制。所以不进行判断是否取完最后一行,就继续取数会发生报错。

DELIMITER ;;
CREATE PROCEDURE test_mysql_cursor_loop()
BEGIN
declare v_total int default 0;
declare i int default 0;
declare str1 int;
declare str2 varchar(255);
DECLARE stuCursor CURSOR FOR SELECT s1,s2 FROM t;
select count(s2) into v_total from t;
OPEN stuCursor;
stuLoop:LOOP
IF i = v_total THEN LEAVE stuLoop; end if;
FETCH stuCursor INTO str1,str2;
SELECT str1,str2;
set i = i+1;
end loop stuLoop;
END;;
DELIMITER ;

二、执行过程解析

这个存储过程在MySQL内部转化为存储过程指令如下:

mysql> show PROCEDURE code test_mysql_cursor_loop;
+-----+---------------------------------------------+
| Pos | Instruction |
+-----+---------------------------------------------+
| 0 | set v_total@0 0 |
| 1 | set i@1 0 |
| 2 | set str1@2 NULL |
| 3 | set str2@3 NULL |
| 4 | cpush stuCursor@0: SELECT s1,s2 FROM t |
| 5 | stmt "select count(s2) into v_total from t" |
| 6 | copen stuCursor@0 |
| 7 | jump_if_not 9(9) (i@1 = v_total@0) |
| 8 | jump 13 |
| 9 | cfetch stuCursor@0 str1@2 str2@3 |
| 10 | stmt "SELECT str1,str2" |
| 11 | set i@1 (i@1 + 1) |
| 12 | jump 7 |
| 13 | cclose stuCursor@0 |
| 14 | cpop 1 |
+-----+---------------------------------------------+
15 rows in set (0.00 sec)

其中:

  • v_total@0的 @0 代表这是第一个自定义变量。

  • stuCursor@0的 @0 代表这是第一个cursor变量。

从指令可以看出cursor的运行需要经过几个过程:

1、cpush

这个用于注册一个cursor,初始化堆栈。

2、copen

这里会先运行SELECT s1,s2 FROM t指令,让cursor获得表的列信息,然后调用cpush,经过cpush->open来打开一个cursor,用于后续获取表数据。

3、cfetch

这个用于从cursor获取的数据赋值给自定义变量str1,str2,然后传递给client端显示。注意到这里用了jump 7来循环取数据。

4、cclose

关闭cursor。

5、cpop

把当前cursor从堆栈释放掉。

上面循环取数和退出机制如下:

jump_if_not 9(9) (i@1 = v_total@0)用于判断i@1是否等于v_total@0,如果不等于的话当前指令就跳转到第9个指令,继续执行cfetch。

如果i@1等于v_total@0的话就继续执行下一条jump 13关闭cursor退出当前循环。set i@1 (i@1 + 1)用于计数,jump 7用于继续循环取数。

三、注意事项

str1和str2的类型和数量必须与declare cursor的一致,如果声明不正确就会导致cfetch出错。

因为declare str1和str2之后,mysql就会对这两个列建立一张临时表,当cfetch数据之后就会把数据存入这张表,后续用户select的时候就从这张临时表取数据来显示,所以就必须进行正确的变量声明。

Enjoy MySQL

文章推荐:

GreatSQL MGR FAQ

https://mp.weixin.qq.com/s/J6wkUpGXw3YkyEUJXiZ9xA

万答#12,MGR整个集群挂掉后,如何才能自动选主,不用手动干预

https://mp.weixin.qq.com/s/07o1poO44zwQIvaJNKEoPA

『2021数据技术嘉年华·ON LINE』:《MySQL高可用架构演进及实践》

https://mp.weixin.qq.com/s/u7k99y6i7riq7ScYs7ySnA

一条sql语句慢在哪之抓包分析

https://mp.weixin.qq.com/s/AYibbzl860D90rOeyjB6IQ

万答#15,都有哪些情况可能导致MGR服务无法启动

https://mp.weixin.qq.com/s/inSGpd0Q_XIl2Mb-VsvNsA

技术分享 | 为什么MGR一致性模式不推荐AFTER

https://mp.weixin.qq.com/s/rNeq479RNsklY1BlfKOsYg

关于 GreatSQL

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

Gitee:

https://gitee.com/GreatSQL/GreatSQL

GitHub:

https://github.com/GreatSQL/GreatSQL

Bilibili:

https://space.bilibili.com/1363850082/video

微信&QQ群:

可搜索添加GreatSQL社区助手微信好友,发送验证信息“加群”加入GreatSQL/MGR交流微信群

QQ群:533341697

微信小助手:wanlidbc

本文由博客一文多发平台 OpenWrite 发布!

解析MySQL存储过程的游标执行过程的更多相关文章

  1. MySQL存储过程之游标实战

    MySQL存储过程之游标实战 ​ 博主日前在解决一个项目需求时,没有什么好的方法,于是就来学习存储过程了,之前也是接触过,奈何年少贪玩,竟是全部又还给了大学老师-苦不堪言呐-. ​ 先说一下业务需求吧 ...

  2. MariaDB MariaDB、MySQL存储过程、游标基础应用举例说明

    MariaDB.MySQL存储过程.游标基础应用举例说明 by:授客 QQ:1033553122 测试环境: MariaDB-10.0.19-centos7-x86_64 实践操作: # 创建测试数据 ...

  3. mysql存储过程之游标遍历数据表

    原文:mysql存储过程之游标遍历数据表 今天写一个mysql存储过程,根据自己的需求要遍历一个数据表,因为对存储过程用的不多,语法不甚熟悉,加之存储过程没有调试环境,花了不少时间才慢慢弄好,故留个痕 ...

  4. MySQL存储过程-->通过游标遍历和异常处理迁移数据到历史表

    -- 大表数据迁移,每天凌晨1点到5点执行,执行间隔时间10分钟,迁移旧数据到历史表. DELIMITER $$ USE `dbx`$$ DROP PROCEDURE IF EXISTS `pro_x ...

  5. MYSQL存储过程、游标、触发器

    MySQL5 中添加了存储过程的支持. 大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成  存储过程简单来说,就是为以后的使用而保存的一 ...

  6. MySQL存储过程和游标

    一.存储过程 什么是存储过程,为什么要使用存储过程以及如何使用存储过程,并且介绍创建和使用存储过程的基本语法. 什么是存储过程: 存储过程可以说是一个记录集,它是由一些T-SQL语句组成的代码块,这些 ...

  7. MySQL存储过程实现动态执行SQL

    --存储过程名和参数,参数中in表示传入参数,out标示传出参数,inout表示传入传出参数 create procedure p_procedurecode(in sumdate varchar(1 ...

  8. mysql存储过程之游标

    MySQL5 中添加了存储过程的支持.     大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成     存储过程简单来说,就是为以后的 ...

  9. MYSQL学习拓展一:MySQL 存储过程之游标的使用!

    一.MySQL游标的概念 游标介绍: MySQL的游标(cursor)是一个重要的概念,通过查找资料与自己的理解,主要得出以下几点关于自己的理解. 有数据缓冲的思想:游标的设计是一种数据缓冲区的思想, ...

随机推荐

  1. MySQL 事务常见面试题总结 | JavaGuide 审核中

    <Java 面试指北>来啦!这是一份教你如何更高效地准备面试的小册,涵盖常见八股文(系统设计.常见框架.分布式.高并发 ......).优质面经等内容. 本文原发于 MySQL知识点&am ...

  2. 编程语言与python与pycharm的下载

    目录 编程语言的发展史 编程语言的分类 python解释器 python解释器的下载与安装 环境变量 执行python程序方式 pycharm编辑器 编程语言的发展史 机器语言是最开始的编程语言,之后 ...

  3. 【ACM程序设计】动态规划 第二篇 LCS&LIS问题

    动态规划 P1439 [模板]最长公共子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述 给出 1,2,-,n 的两个排列 P1 和 P2 ,求它们的最长公共子序列. ...

  4. 第6组 Alpha冲刺 (5/6)

    目录 1.1 基本情况 1.2 冲刺概况汇报 1.郝雷明 2. 方梓涵 3.董翔云 4.杜筱 5.詹鑫冰 6.黄少丹 7.曹兰英 8.鲍凌函 9.曾丽莉 10.吴沅静 1.3 冲刺成果展示 1.1 基 ...

  5. 两个月吃透阿里P9推荐260页SpringBoot2企业应用实战pdf入职定P6+

    前言 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置 ...

  6. transforms.py

    from PIL import Image from torchvision import transforms #python的用法-->tensor数据类型 #通过transforms.To ...

  7. js 生成的html class属性失效问题

    var html = '<fieldset class="struct-info" id="SlopeZY"><legend>变坡点(Z ...

  8. Windows启动谷歌浏览器Chrome失败(应用程序无法启动,因为应用程序的并行配置不正确)解决方法

    目录 一.系统环境 二.问题描述 三.解决方法 一.系统环境 Windows版本 系统类型 浏览器Chrome版本 Windows 10 专业版 64 位操作系统, 基于 x64 的处理器 版本 10 ...

  9. jenkins页面一直在Please wait while Jenkins is getting ready to work ...

    原因:因为访问官网太慢.我们只需要换一个源,不使用官网的源即可. 1.找到jenkins工作目录 find / -name *.UpdateCenter.xml 2.修改文件中的url,随后重启就行了 ...

  10. org/apache/poi/POIXMLTypeLoader或者java.lang.NoSuchFieldError: RETURN_NULL_AND_BLANK

    原因是之前我的poi和ooxml版本有点低, 解决方案 将两者版本提高,我是将两者的版本都提高到了3.15