MySQL游标概念与用法详解
作者:webbc 发布时间:2024-01-23 05:20:54
本文实例讲述了MySQL游标概念与用法。分享给大家供大家参考,具体如下:
1、游标的概念(Cursor)
一条sql,对应N条资源,取出资源的接口,就是游标,沿着游标,可以一次取出1行。如果开发过安卓的同学应该知道有一个Api是Cursor,也是读取SQLite数据库用的,和这个有点类似。
2、使用游标的步骤
(1)声明
使用declare进行声明
declare 游标名 cursor for select_statement
(2)打开游标
使用open进行打开
open 游标名
(3)从游标中取值
使用fetch进行取值
fetch 游标名 into var1,var2[,...] --将取到的一行赋值给多个变量
(4)关闭游标
使用close关闭游标
close 游标名
3、创建一个简单的游标
需求:从商品表中读取第一行数据
商品表(goods)数据:
注意:我这里已经将MySQL的结束标识符改为 $,如果要知道怎么设置为$,请参考前面一篇文章:MySQL触发器。
定义:
create procedure p12()
begin
/*定义三个变量用于存放商品id,商品名称,商品库存量*/
declare row_gid int ;
declare row_name varchar(20);
declare row_num int;
declare getgoods cursor for select gid,name,num from goods; --定义游标
open getgoods; --打开游标
fetch getgoods into row_gid,row_name,row_num;--从游标中取值
select row_name,row_num; --显示操作
close getgoods; --关闭游标
end$
输出结果:
4、多次取值操作
create procedure p13()
begin
declare row_gid int ;
declare row_name varchar(20);
declare row_num int;
declare getgoods cursor for select gid,name,num from goods;
open getgoods;
fetch getgoods into row_gid,row_name,row_num;
select row_name,row_num;
fetch getgoods into row_gid,row_name,row_num;
select row_name,row_num;
fetch getgoods into row_gid,row_name,row_num;
select row_name,row_num;
fetch getgoods into row_gid,row_name,row_num;
select row_name,row_num;
close getgoods;
end$
输出:
注意:当游标读到末尾,如果继续进行取值操作会发生报错
5、游标循环表中的所有数据
(1)使用计数器来循环
create procedure p14()
begin
declare cnt int default 0;
declare i int default 0;
declare row_gid int ;
declare row_name varchar(20);
declare row_num int;
declare getgoods cursor for select gid,name,num from goods;
select count(*) into cnt from goods;
open getgoods;
repeat
fetch getgoods into row_gid,row_name,row_num;
select row_name,row_num;
set i:= i+1;
until i >= cnt end repeat;
close getgoods;
end$
输出结果:
(2)使用越界标志来控制循环
在mysql cursor中,可以声明declare continue handler
来操作1个越界标志
语法:
declare continue handler for NOT FOUND statement;
使用:
create procedure p15()
begin
declare row_gid int ;
declare row_name varchar(20);
declare row_num int;
declare have int default 1;
declare getgoods cursor for select gid,name,num from goods;
declare continue handler for NOT FOUND set have:= 0;
open getgoods;
repeat
fetch getgoods into row_gid,row_name,row_num;
select row_name,row_num;
until have = 0 end repeat;
close getgoods;
end$
输出结果:
注意:这里发生了错误,这里输出了4行数据,而表中只有3行数据,而且还爆出了警告,后面会说怎么结果这个问题。
程序执行逻辑:
循环游标->fetch第三条数据->显示->fetch第四条数据->没有数据->设置have=0操作->执行continue Handler->程序不退出,执行显示操作->还是显示第三条数据
6、continue和exit的区别
continue:若没有数据返回,程序继续,并将变量IS_FOUND设为0,这种情况是出现在select XX into XXX from tablename的时候发生的。
exit:若没有数据返回,退出程序,并将变量IS_FOUND设为0,这种情况是出现在select XX into XXX from tablename的时候发生的。
使用exit来替换continue:
使用exit就不会出现上面的那种情况了,程序执行逻辑:
循环游标->fetch到第三条数据->显示->第四次fetch操作->没有数据->设置 have=0操作->程序直接退出exit
所以就没有显示出第四条数据。
create procedure p16()
begin
declare row_gid int ;
declare row_name varchar(20);
declare row_num int;
declare have int default 1;
declare getgoods cursor for select gid,name,num from goods;
declare exit handler for NOT FOUND set have:= 0;
open getgoods;
repeat
fetch getgoods into row_gid,row_name,row_num;
select row_name,row_num;
until have = 0 end repeat;
close getgoods;
end$
输出结果:
7、正确的游标循环
在一些特殊的情况中,我们可以读到的数据为空,或者压根sql语句就有错误,我们不能避免出现这种情况,所以我们要正确的使用游标循环操作。
首先应该创建游标,然后打开游标后,应先手动进行fetch操作获取到一行数据,然后再通过循环,在循环里先做处理内容,后进行fetch操作。这样如果在手动获取数据的期间就没有获得到数据的话,就会执行have = 0,如果是repeat循环,然后进入repeat循环,先输出null数据,最后又进行获取,这样运行到until时就会退出循环;如果是while循环,压根就不进去while循环里,就不会有任何1行输出。
(1)repeat循环:
create procedure p17()
begin
declare row_gid int;
declare row_name varchar(20);
declare row_num int;
declare have int default 1;
declare getgoods cursor for select gid,name,num from goods where 0;
declare continue handler for NOT FOUND set have:= 0;
open getgoods;
fetch getgoods into row_gid,row_name,row_num;
repeat
select row_name,row_num;
fetch getgoods into row_gid,row_name,row_num;
until have = 0 end repeat;
close getgoods;
end$
输出结果:
(2)while循环:
create procedure p18()
begin
declare row_gid int;
declare row_name varchar(20);
declare row_num int;
declare have int default 1;
declare getgoods cursor for select gid,name,num from goods where 0;
declare continue handler for NOT FOUND set have:= 0;
open getgoods;
fetch getgoods into row_gid,row_name,row_num;
while have = 1 do
select row_name,row_num;
fetch getgoods into row_gid,row_name,row_num;
end while;
close getgoods;
end$
输出结果:
希望本文所述对大家MySQL数据库计有所帮助。
来源:https://blog.csdn.net/baochao95/article/details/53239463


猜你喜欢
- 本文将介绍 5 种基于 Plotly 的可视化方法,你会发现,原来可视化不仅可用直方图和箱形图,还能做得如此动态好看甚至可交互。那么,Plo
- 最近,同事需要从数个表中查询用户的业务和报告数据,写了一个SQL语句,查询比较慢:Select S.Name,S.AccountantCod
- 当使用for语句循环(迭代)pandas.DataFrame时,简单的使用for语句便可以取得返回列名,因此使用重复使用for方法,便可以获
- 众所周知tensorflow造势虽大却很难用,因此推荐使用Keras,它缺省是基于tensorflow的,但通过修改keras.json也可
- 在使用tp5时候把它部署到服务器上发现一个奇葩的事情,就是它默认访问config配置的默认页,无论怎么跳转到其他接口都不好使,最终重写了&n
- PHP现在推出5.3.0版本了,不过下载的时候有几个不同版本选择。那就是VC6 X86和VC9 X86。首先我来解答:VC6是什么?VC6就
- 官网:https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads我的系统
- 前言Vuex 和 Pinia 是用于管理 Vue.js 应用程序状态的标准 Vue.js 库。让我们比较一下他们的代码、语言、功能和社区支持
- 数据库发生阻塞和死锁的现象:一、数据库阻塞的现象:第一个连接占有资源没有释放,而第二个连接需要获取这个资源。如果第一个连接没有提交或者回滚,
- 前言笔者最近正在学习Pandas数据分析,将自己的学习笔记做成一套系列文章。本节主要记录Pandas中数据的合并(concat和append
- mysql高效查询mysql牺牲了group by来增加left join的速度(前提是加了索引)。user表:10万数据实例1: 200秒
- selenium 安装与 chromedriver安装我们前文提到,Python脚本中使用了selenium库,而selenium又通过ch
- 本文实例讲述了MySQL重定位数据目录的实现方法。分享给大家供大家参考。具体方法如下:MySQL允许重定位数据目录或其中的成员,这里就来介绍
- datetime 时间包认识 datetime 时间包:date:日期;time:时间;所以 datetime 就是 日期与时间的结合体使用
- 前言在做接口自动化的时候,经常会遇到一些参数是需要加密的,比如密码参数。加密规则一般开发也不愿意告诉你,会直接给你一个jar包,让你调用ja
- 实现思路和详细解读1. 获取 Fashion 数据、处理数据(1)本次实践项目用到的是 Fashion 数据集,包含 10 个类别的服饰灰度
- asp时间加减运算 和转换问题 a=2007-07-24 2:23:15 b=2005-06-25 2:23:15 问题1 如何将a转换成2
- 前言哈希 又称作 “散列”,它接收任何一组任意长度的输入信息,通过 哈希 算法变换成固定长度的数据指
- 这本是课程的一个作业研究搜索算法,当时研究了一下Tkinter,然后写了个很简单的机器人走迷宫的界面,并且使用了各种搜索算法来进行搜索,如下
- 目录1.jupyter2.jupyter基础操作2.1windows更新pip库2.2jupyter安装2.3初次启动jupyter2.4设