玩转Mysql系列 - 第19篇:游标详解
这是Mysql系列第19篇。
环境:mysql5.7.25,cmd命令中进行演示。
代码中被[]包含的表示可选,|符号分开的表示可选其一。
需求背景
当我们需要对一个select的查询结果进行遍历处理的时候,如何实现呢?
此时我们需要使用游标,通过游标的方式来遍历select查询的结果集,然后对每行数据进行处理。
本篇内容
-
游标定义
-
游标作用
-
游标使用步骤
-
游标执行过程详解
-
单游标示例
-
嵌套游标示例
准备数据
创建库:javacode2018
创建表:test1、test2、test3
/*建库javacode2018*/
drop database if exists javacode2018;
create database javacode2018;/*切换到javacode2018库*/
use javacode2018;DROP TABLE IF EXISTS test1;
CREATE TABLE test1(a int,b int);
INSERT INTO test1 VALUES (1,2),(3,4),(5,6);DROP TABLE IF EXISTS test2;
CREATE TABLE test2(a int);
INSERT INTO test2 VALUES (100),(200),(300);DROP TABLE IF EXISTS test3;
CREATE TABLE test3(b int);
INSERT INTO test3 VALUES (400),(500),(600);
游标定义
游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次一行遍历数据的能力。
游标只能在存储过程和函数中使用。
游标的作用
如sql:
select a,b from test1;
上面这个查询返回了test1中的数据,如果我们想对这些数据进行遍历处理,此时我们就可以使用游标来进行操作。
游标相当于一个指针,这个指针指向select的第一行数据,可以通过移动指针来遍历后面的数据。
游标的使用步骤
声明游标:这个过程只是创建了一个游标,需要指定这个游标需要遍历的select查询,声明游标时并不会去执行这个sql。
打开游标:打开游标的时候,会执行游标对应的select语句。
遍历数据:使用游标循环遍历select结果中每一行数据,然后进行处理。
关闭游标:游标使用完之后一定要关闭。
游标语法
声明游标
DECLARE 游标名称 CURSOR FOR 查询语句;
一个begin end中只能声明一个游标。
打开游标
open 游标名称;
遍历游标
fetch 游标名称 into 变量列表;
取出当前行的结果,将结果放在对应的变量中,并将游标指针指向下一行的数据。
当调用fetch的时候,会获取当前行的数据,如果当前行无数据,会引发mysql内部的
NOT FOUND
错误。
关闭游标
close 游标名称;
游标使用完毕之后一定要关闭。
单游标示例
写一个函数,计算test1表中a、b字段所有的和。
创建函数:
/*删除函数*/
DROP FUNCTION IF EXISTS fun1;
/*声明结束符为$*/
DELIMITER $
/*创建函数*/
CREATE FUNCTION fun1(v_max_a int)RETURNS intBEGIN/*用于保存结果*/DECLARE v_total int DEFAULT 0;/*创建一个变量,用来保存当前行中a的值*/DECLARE v_a int DEFAULT 0;/*创建一个变量,用来保存当前行中b的值*/DECLARE v_b int DEFAULT 0;/*创建游标结束标志变量*/DECLARE v_done int DEFAULT FALSE;/*创建游标*/DECLARE cur_test1 CURSOR FOR SELECT a,b from test1 where a<=v_max_a;/*设置游标结束时v_done的值为true,可以v_done来判断游标是否结束了*/DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done=TRUE;/*设置v_total初始值*/SET v_total = 0;/*打开游标*/OPEN cur_test1;/*使用Loop循环遍历游标*/a:LOOP/*先获取当前行的数据,然后将当前行的数据放入v_a,v_b中,如果当前行无数据,v_done会被置为true*/FETCH cur_test1 INTO v_a, v_b;/*通过v_done来判断游标是否结束了,退出循环*/if v_done THENLEAVE a;END IF;/*对v_total值累加处理*/SET v_total = v_total + v_a + v_b;END LOOP;/*关闭游标*/CLOSE cur_test1;/*返回结果*/RETURN v_total;END $
/*结束符置为;*/
DELIMITER ;
上面语句执行过程中可能有问题,解决方式如下。
错误信息:Mysql 创建函数出现This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary
mysql的设置默认是不允许创建函数
解决办法1:
执行:
SET GLOBAL log_bin_trust_function_creators = 1;
不过 重启了 就失效了
注意:有主从复制的时候 从机必须要设置 不然会导致主从同步失败
解决办法2:
在my.cnf里面设置
log-bin-trust-function-creators=1
不过这个需要重启服务
见效果:
mysql> SELECT a,b FROM test1;
+------+------+
| a | b |
+------+------+
| 1 | 2 |
| 3 | 4 |
| 5 | 6 |
+------+------+
3 rows in set (0.00 sec)mysql> SELECT fun1(1);
+---------+
| fun1(1) |
+---------+
| 3 |
+---------+
1 row in set (0.00 sec)mysql> SELECT fun1(2);
+---------+
| fun1(2) |
+---------+
| 3 |
+---------+
1 row in set (0.00 sec)mysql> SELECT fun1(3);
+---------+
| fun1(3) |
+---------+
| 10 |
+---------+
1 row in set (0.00 sec)
游标过程详解
以上面的示例代码为例,咱们来看一下游标的详细执行过程。
游标中有个指针,当打开游标的时候,才会执行游标对应的select语句,这个指针会指向select结果中第一行记录。
当调用fetch 游标名称
时,会获取当前行的数据,如果当前行无数据,会触发NOT FOUND
异常。
当触发NOT FOUND
异常的时候,我们可以使用一个变量来标记一下,如下代码:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done=TRUE;
当游标无数据触发NOT FOUND
异常的时候,将变量v_down
的值置为TURE
,循环中就可以通过v_down
的值控制循环的退出。
如果当前行有数据,则将当前行数据存到对应的变量中,并将游标指针指向下一行数据,如下语句:
fetch 游标名称 into 变量列表;
嵌套游标
写个存储过程,遍历test2、test3,将test2中的a字段和test3中的b字段任意组合,插入到test1表中。
创建存储过程:
/*删除存储过程*/
DROP PROCEDURE IF EXISTS proc1;
/*声明结束符为$*/
DELIMITER $
/*创建存储过程*/
CREATE PROCEDURE proc1()BEGIN/*创建一个变量,用来保存当前行中a的值*/DECLARE v_a int DEFAULT 0;/*创建游标结束标志变量*/DECLARE v_done1 int DEFAULT FALSE;/*创建游标*/DECLARE cur_test1 CURSOR FOR SELECT a FROM test2;/*设置游标结束时v_done1的值为true,可以v_done1来判断游标cur_test1是否结束了*/DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done1=TRUE;/*打开游标*/OPEN cur_test1;/*使用Loop循环遍历游标*/a:LOOPFETCH cur_test1 INTO v_a;/*通过v_done1来判断游标是否结束了,退出循环*/if v_done1 THENLEAVE a;END IF;BEGIN/*创建一个变量,用来保存当前行中b的值*/DECLARE v_b int DEFAULT 0;/*创建游标结束标志变量*/DECLARE v_done2 int DEFAULT FALSE;/*创建游标*/DECLARE cur_test2 CURSOR FOR SELECT b FROM test3;/*设置游标结束时v_done1的值为true,可以v_done1来判断游标cur_test2是否结束了*/DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done2=TRUE;/*打开游标*/OPEN cur_test2;/*使用Loop循环遍历游标*/b:LOOPFETCH cur_test2 INTO v_b;/*通过v_done1来判断游标是否结束了,退出循环*/if v_done2 THENLEAVE b;END IF;/*将v_a、v_b插入test1表中*/INSERT INTO test1 VALUES (v_a,v_b);END LOOP b;/*关闭cur_test2游标*/CLOSE cur_test2;END;END LOOP;/*关闭游标cur_test1*/CLOSE cur_test1;END $
/*结束符置为;*/
DELIMITER ;
见效果:
mysql> DELETE FROM test1;
Query OK, 9 rows affected (0.00 sec)mysql> SELECT * FROM test1;
Empty set (0.00 sec)mysql> CALL proc1();
Query OK, 0 rows affected (0.02 sec)mysql> SELECT * from test1;
+------+------+
| a | b |
+------+------+
| 100 | 400 |
| 100 | 500 |
| 100 | 600 |
| 200 | 400 |
| 200 | 500 |
| 200 | 600 |
| 300 | 400 |
| 300 | 500 |
| 300 | 600 |
+------+------+
9 rows in set (0.00 sec)
成功插入了9条数据。
总结
-
游标用来对查询结果进行遍历处理
-
游标的使用过程:声明游标、打开游标、遍历游标、关闭游标
-
游标只能在存储过程和函数中使用
-
一个begin end中只能声明一个游标
-
掌握单个游标及嵌套游标的使用
-
大家下去了多练习一下,熟练掌握游标的使用
相关文章:
玩转Mysql系列 - 第19篇:游标详解
这是Mysql系列第19篇。 环境:mysql5.7.25,cmd命令中进行演示。 代码中被[]包含的表示可选,|符号分开的表示可选其一。 需求背景 当我们需要对一个select的查询结果进行遍历处理的时候,如何实现呢? 此时我们需要使…...
【量化分析】Python 布林线( Bollinger)概念
一、说明 布林线(BOLL),Bollinger Bands,利用统计原理,求出股价的标准差及其信赖区间,从而确定股价的波动范围及未来走势,利用波带显示股价的安全高低价位,因而也被称为布林带。 二、布林带基本概念 布林线…...
MySQL的权限管理与远程访问
MySQL的权限管理 1、授予权限 授权命令: grant 权限1,权限2,…权限n on 数据库名称.表名称 to 用户名用户地址 identified by ‘连接口令’; 该权限如果发现没有该用户,则会直接新建一个用户。 比如 grant select,insert,delete,drop on atguigudb.…...
在Qt创建的UI中放一个显示点云的窗口(PCL+QT5)
1、首先在Qt Designer创建UI后,拖一个Widget窗口出来 2、在对象查看器中右击该Widget,选择提升窗口部件,如下操作: 3、把UI转出来放在VS项目中,其中你的UI代码头文件会自带QVTKOpenGLNativeWidget.h,当然你…...
element ui el-table分页多选功能
selection-change:当选择项发生变化时会触发该事件(当分页切换时,选中的数据都会自动清空) 一、在el-table中添加 :row-key“id” <el-table :data"tableData" border style"width: 95%" selection-change…...
理解网络通信的基础:OSI七层模型与TCP/IP五层模型
在今天的数字化世界中,网络通信已经成为我们日常生活和商业活动的重要组成部分。为了更好地理解和管理网络通信,网络工程师和管理员使用不同的模型来组织和解释网络协议和通信过程。本文将介绍两种最重要的网络模型:OSI七层模型和TCP/IP五层模…...
Python爬虫-爬取文档内容,如何去掉文档中的表格,并保存正文内容
前言 本文是该专栏的第58篇,后面会持续分享python爬虫干货知识,记得关注。 做过爬虫项目的同学,可能或多或少爬取过文档数据,比如说“政务网站,新闻网站,小说网站”等平台的文档数据。爬取文档数据,笔者这里就不过多详述,而本文,笔者将主要介绍在爬取文档数据的过程中…...
【使用Cpolar和Qchan搭建自己的个人图床】
文章目录 前言1. Qchan网站搭建1.1 Qchan下载和安装1.2 Qchan网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar云端设置2.2 Cpolar本地设置 3. 公网访问测试总结 前言 图床作为云存储的一项重要应用场景,在大量开发人员的努力下,已经开发出大…...
flutter解决多个类名重名问题
Try using ‘as prefix’ for one of the import directives, or hiding the name from all but one of the imports. Flutter遇到这种错误,意思是你自己的import的库的类名跟一另一个导入的库,或者系统的类名名字相同.解决方法,把自己的一个类名用as 加一个前缀,使用的时候 用…...
微信小程序 按钮颜色
<button type"primary">主要按钮样式类型</button> <button type"default">默认按钮样式类型</button> <button type"warn">警告按钮样式类型</button> <view>按钮plain是否镂空</view> <bu…...
【云原生】kubectl常用命令大全
目录 一、资源管理方法 kubectl 的命令大全 二、 kubectl常用命令大全 2.2 项目的生命周期:创建-->发布-->更新-->回滚-->删除 1、创建 kubectl create命令 2、发布 kubectl expose命令 3、更新 kubectl set 4、回滚 kubectl rollou…...
git pull
目录 git pull 原理: git pull遇到问题怎么解决: git pull 原理: git pull 是 Git 版本控制系统中的一个命令,用于从远程存储库更新本地工作目录。它实质上是两个命令的组合:git fetch 和 git merge。 当你执行 gi…...
C++学习之运算符与表达式
算数运算符 基本的算数运算有加法、减法、乘法、除法和取模(求余数),对应的算数运算符分别为:、-、*、/、%。至于用法,大家应该耳熟能详,这里不再过多赘述。 自增与自减运算符 运算符说明自增运算符&…...
vue使用谷歌地图实现地点查询
效果 代码 首先在index.html中引入谷歌地图资源 <script src"https://maps.googleapis.com/maps/api/js?key你的api密钥&librariesplaces"></script>页面中 <template><div class"pac-card div-style" id"pac-card"…...
前端该了解的网络知识
网络 前端开发需要了解的网络知识 URL URL(uniform resource locator,统一资源定位符)用于定位网络服务. URL是一个固定格式的字符串 它表达了: 从网络中哪台计算机(domain)中的哪个服务(port),获取服务器上资源的路径(path),以及要用什么样的协议通信(schema). 注意: 当…...
python3在虚拟环境实用vscode调试错误输出ModuleNotFoundError: No module named ‘django‘解决方法
Exception has occurred: ImportError Couldnt import Django. Are you sure its installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?File "/data/mountain-backend/src/manage.py", line 8, i…...
如何获得一个Oracle 23c免费开发者版
获取23c开发者版 简单介绍可参考这里。 获取数据库可以参考这篇文章Introducing Oracle Database 23c Free – Developer Release或这里。 Docker Image 这是最快的方法。在OCI上创建一个计算实例,然后就可以拉取image使用了。 docker的安装和配置不赘述了。 …...
机器学习策略二——优化深度学习系统
进行误差分析 (Carrying out error analysis) 如果你希望让学习算法能够胜任人类能做的任务,但你的学习算法还没有达到人类的表现,那么人工检查一下你的算法犯的错误也许可以让你了解接下来应该做什么。这个过程称为错误分析。 假设你正在调试猫分类器…...
Pytorch Advanced(三) Neural Style Transfer
神经风格迁移在之前的博客中已经用keras实现过了,比较复杂,keras版本。 这里用pytorch重新实现一次,原理图如下: from __future__ import division from torchvision import models from torchvision import transforms from PIL…...
英飞凌TC3xx--深度手撕HSM安全启动(三)--TC3xx HSM系统架构
今天聊TC3xx HSM系统,包括所用内核、UCB相关信息、Host和HSM交互方式。 1、HSM系统架构 下图来源于英飞凌官网培训材料。 TC3xx的HSM内核是一颗32位的ARM Cortex M3,主频可达100MHz,支持对称算法AES128、非对称算法PKC(Public Key Crypto) ECC256、Hash SHA2,以及T…...
黑马JVM总结(五)
(1)方法区 它是所有java虚拟机 线程共享的区,存储着跟类的结构相关的信息,类的成员变量,方法数据,成员方法,构造器方法,特殊方法(类的构造器) 方法区在虚拟机…...
C语言入门Day_18 判断和循坏的小结
目录 前言: 1.判断 2.循环 3.课堂笔记 4.思维导图 前言: 判断语句和循环语句都可以大致分为三个部分,第一个部分是固定的语法格式;第二部分是代码的执行顺序,第三部分是判断和循环成立与否的判断条件。 1.判断 1…...
mac 好用的工具推荐
mac 好用的工具推荐 落雪:全网的音乐畅听,下载地址:https://github.com/lyswhut/lx-music-desktopMotrix: 免费下载工具,下载地址:https://xclient.info/s/motrix.html#versionsDownie:视频下载工具&#x…...
星际争霸之小霸王之小蜜蜂(十二)--猫有九条命
系列文章目录 星际争霸之小霸王之小蜜蜂(十一)--杀杀杀 星际争霸之小霸王之小蜜蜂(十)--鼠道 星际争霸之小霸王之小蜜蜂(九)--狂鼠之灾 星际争霸之小霸王之小蜜蜂(八)--蓝皮鼠和大…...
【软件分析/静态分析】chapter8 课程11/12 指针分析—上下文敏感(Pointer Analysis - Context Sensitivity)
🔗 课程链接:李樾老师和谭天老师的: 南京大学《软件分析》课程11(Pointer Analysis - Context Sensitivity I)_哔哩哔哩_bilibili 南京大学《软件分析》课程12(Pointer Analysis - Context Sensitivity II&…...
时间复杂度与空间复杂度详解
时间复杂度与空间复杂度详解🦖 一、算法效率1.1 如何衡量一个算法的好坏1.2 算法的复杂度 二、时间复杂度2.1 时间复杂度的定义2.2 大O的渐进表示法2.3 如何记录表示算法复杂度 三、空间复杂度3.1 空间复杂度的定义3.2 小试牛刀 一、算法效率 1.1 如何衡量一个算法…...
目录操作函数
mkdir函数 rmdir函数 删除空目录 rename函数 换名 chdir函数 修改当前的工作目录 getcwd函数 获取当前工作的路径...
PlantUML入门教程:画时序图
软件工程中会用到各种UML图,例如用例图、时序图等。那我们能不能像写代码一样去画图呢? 今天推荐一款软件工程师的作图利器--PlantUML,它能让你用写代码的方式快速画出UML图。 一、什么是PlantUML? PlantUML是一个允许你快速作出…...
C#范围运算符
C#8.0语法中,范围运算符是一种用于快速截取序列的运算符,其语法为 “start…end”,表示从序列的 “start” 索引处开始,一直截取到"end" 索引处为止(包括 “end” 索引处的元素)。范围运算符主要…...
云数据库知识学习——云数据库产品、云数据库系统架构
一、云数据库产品 1.1、云数据库厂商概述 云数据库供应商主要分为三类。 ① 传统的数据库厂商,如 Teradata、Oracle、IBM DB2 和 Microsoft SQL Server 等。 ② 涉足数据库市场的云供应商,如 Amazon、Google、Yahoo!、阿里、百度、腾讯…...
荣耀手机商城官方网站荣耀60pro/seo公司推广宣传
有一些很古老的教程,一般都是走编译安装路线的,本文是教你不需要编译,而且随时都可以跟随 CentOS 升级 Proftpd 到最新版本,以避免可能的漏洞攻击。利用 Proftpd 现成的配置以及设置好的各种模块,可以实现 sftp 和 ssh…...
中关村网站建设/家电企业网站推广方案
2020/08/08每日二十个英语单词 transfer molding 传递模塑法,连续自动送进成型transfer rate 传输速率transfer, bit aligned block 位定位式区块传输transfer, bit-block (BitBLT) 位区块传输transfer, block mode 资料段传输模式transfer, burst bus 资料组总线传…...
网站建设管理与政府/超级优化大师下载
期待着,盼望着,五一劳动节终于要到来了!开心!让我们欢呼雀跃! 小编此时此刻的心情,无法形容,唯有吟诗一首: 啊!劳动节~~ 真高兴呀! 真高兴! 哎呀!…...
图片上传网站变形的处理/seo网络营销招聘
目录 1. 下载IEDriverServer.exe 2. 将IEDriverServer.exe或IEDriverServer.64.exe放在C:\ProgramData\Anaconda3\Scripts下面 3. 测试代码 1. 下载IEDriverServer.exe 我在太平洋电脑网下载的,得到两个IEDriverServer.exe和IEDriverServer.64.exe,这…...
nas wordpress 外网访问/品牌推广的步骤和技巧
阿里巴巴实时计算部-昆仑 最近在学习Flink的Fault Tolerance,了解到Flink在Chandy Lamport Algorithm的基础上扩展实现了一套分布式Checkpointing机制,这个机制在论文"Lightweight Asynchronous Snapshots for Distributed Dataflows"中进行了…...
html5笑话网站源码/谷歌的推广是怎么样的推广
1:关系型数据库。 比如常见的 mysql、oracle、sqlserver 等,这类数据库基本上都支持 jdbc 或者 odbc 链接,所以报表工具基本上都支持。 2:文本文件 常见的 txt、csv、excel 等文本文件,这类文本文件就看各类报表的支…...