本文目录:

1.游标说明

2.使用游标

3.游标使用示例

1.游标说明

游标,有些地方也称为光标。它的作用是在一个结果集中逐条逐条地获取记录行并操作它们。

例如:

其中select是游标所操作的结果集,游标每次fetch一行中的name和age字段,并将每一行的这两个字段赋值给变量var1和var2。

有很多、很多、很多人,很多、很多、很多书都强烈建议:能不用游标尽量不要用游标。因为它违背了集合的理论,集合取数据是一把一把抓,游标取数据的时候一行一行取,每取一行操作一行,而且在每一行上都有额外的资源消耗。总之,游标效率低、资源消耗高。

其实很多领域都有这样的优化:把数据先集中起来,集中到了一定量再一次性处理,这样的处理方式效率要高得多。比如写日志到磁盘上,可以每产生一条日志就刷入磁盘,也可以先产生一堆日志缓存起来,之后一次性刷如磁盘。后者效率要高得多。

集合取数据的时候关注点在于想要什么数据,而不关注怎么去获取数据,游标的关注点则在于怎么获取这些数据:将游标指针作为遍历依据,遍历到哪行数据就返回这行数据然后停下来处理数据,再继续遍历数据。习惯于迭代的人比较喜欢游标,特别是习惯C语言的人,因为游标就是遍历数据行的行为。

在MySQL、MariaDB中实现的游标比较简单,它只有一种遍历方式:逐行向前遍历。MariaDB 10.3后,游标方面支持的更完整一点:支持游标参数。

光标的使用包括声明光标、打开光标、使用光标和关闭光标(MySQL/MariaDB中的游标无需释放)。光标必须声明在处理程序之前,并且在声明保存结果集的变量之后。另外,游标是一种复合语句结构(就像begin...end),只能用于stored procedure或stored function中。

2.使用游标

1.声明游标

DECLARE cursor_name CURSOR FOR select_statement;

其中select_statement是游标需要从中获取的结果集。

例如:

declare cur_city cursor for select id,'name',population from world,city;

在MariaDB 10.3中,支持游标参数,该参数可以传递到select_statement中:

DECLARE cursor_name CURSOR(param1 data_type,param2 data_type2...) FOR select_statement;

例如:

declare cur_stu cursor(min int,max int) for select id,name from Student where id between min and max;

注意,mariaDB 10.3之前的语法也能在10.3版本上执行,因为之前的语法是10.3版本中不带参数的特殊情况。

2.声明处理程序

一般来说,光标是用在逐条取结果集的情况下,所以在使用光标的时候基本都会放在循环结构中循环获取数据存储到变量中。但如何在取完数据后退出循环?

在游标无法获取到下一行数据的时候,将会返回一个1329错误码,这个错误码对应的SQL状态码为"02000",它们等价于NOT FOUND(这几个是等价的,只是MariaDB中分了3类描述问题的代码而已)。这时可以在声明游标后定义一个handler,用于处理NOT FOUND。

例如下面是适合游标NOT FOUND时的CONTINUE处理器,表示当找不到下一行数据时继续执行后面的程序:

DECLARE CONTINUE HANDLER FOR NOT FOUND statement;

对于处理游标的HANDLER,通常statement部分是SET语句,用于设置一些变量。例如:

declare continue handler for not found set var_name=value;

这时,当取不到下一条记录时即已经取完记录时,就设置变量var_name=value。之后就可以通过该变量的值作为退出循环的条件。

关于handler详细内容,见我翻译的MariaDB手册:https://mariadb.com/kb/zh-cn/declare-handler/

3.打开游标

当声明了一个游标后,必须要打开游标才能使用游标。

open cursor_name;

例如:

open cur_city;

对于mariadb 10.3,由于支持游标参数,因此语法为:

open cursor_name(value1,value2);

例如:

open cur_stu(4,10);

4.使用游标(fetch into)

通过fetch into命令将每次fetch到的结果存储到预先定义好的变量中。注意,这个变量必须是本地变量(局部变量),不能是用户自定义变量,且这个变量必须定义在游标声明语句之前。

fetch cursor_name into var_name;

例如:

fetch cur_city into city_id,city_name,city_popcnt;

在上面已经说过了,一般游标都会在循环结构中使用。以下是在repeat结构中使用游标;

repeat

fetch ... into ...

until var_name=value

end repeat;

5.关闭游标

close cursor_name;

例如:

close cur_city;

3.游标使用示例

以下是MariaDB 10.3版本之前(也适用于10.3)的游标使用示例:将表t1和表t2中每行中的某一列作比较,将较大值插入到表t3中。

create or replace table t1(i int);

create or replace table t2(i int);

create or replace table t3(i int);

insert into t1 values(5),(10),(20);

insert into t2 values(15),(30),(10);

delimiter $$

create or replace procedure proc1()

begin

declare done int default false;  /* 用于判断退出循环 */

declare x,y int;                  /* 用于保存fetch结果 */

declare cur1 cursor for select i from t1;    /* fetch t1的游标 */

declare cur2 cursor for select i from t2;    /* fetch t2的游标 */

declare continue handler for not found set done=true;  /* not found时,退出循环 */

open cur1;

open cur2;

my_loop: LOOP

fetch cur1 into x;

fetch cur2 into y;

if done then

leave my_loop;

end if;

if  x <= y then

insert into t3 values(y);

else

insert into t3 values(x);

end if;

end loop;

close cur1;

close cur2;

end$$

delimiter ;

call proc1;

查看表t3:

select * from t3;

+------+

| i    |

+------+

|  15 |

|  30 |

|  20 |

+------+

下面是MariaDB 10.3上使用游标的一个示例:将表t1中i字段某一段数据插入到表t2中。

create or replace table t1(i int);

create or replace table t2(i int);

insert into t1 values(5),(10),(20),(30),(40);

delimiter $$

create or replace procedure proc1(min int,max int)

begin

declare done int default false;

declare x int;

declare cur1 cursor(cmin int,cmax int) for select i from t1 where t1.i between cmin and cmax;

declare continue handler for not found set done=true;

open cur1(min,max);

my_loop: LOOP

fetch cur1 into x;

if done then

leave my_loop;

end if;

insert into t2 values(x);

end loop;

close cur1;

end$$

delimiter ;

call proc1(10,40);

查看t2结果:

MariaDB [test]> select * from t2;

+------+

| i    |

+------+

|  10 |

|  20 |

|  30 |

|  40 |

+------+

mysql中游标能不能更新数据库_MySQL与MariaDB中游标的使用相关推荐

  1. mysql中游标能不能更新数据库_数据库游标更新数据

    SQLServer游标(Cursor)简介和使用说明 游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次以行或者多行前进或向后浏览数据的能力.我们可以把 ...

  2. MySQL中引入存储引擎意义是_mysql学习九:存储引擎、存储过程和函数的引入

    存储引擎: 存储引擎是mysql特有的,共有7种,常用的有myisam.memory.innodb 查看表的存储引擎: show create table 表名; 修改表的存储引擎: alter ta ...

  3. mysql中修改表的还原命令_MySQL的增、删、改、查和备份、恢复的命令

    一.增删改查 1.创建数据库 CREATE DATABASE DBname mysqladmin-u root-p create DBname 2.删除数据库 DROP DATABASE DBname ...

  4. 在MySQL中以下属于ddl语句的_MySQL的DDL语句、DML语句与DCL语句

    背景:近几年,开源数据库逐渐流行起来.由于具有免费使用.配置简单.稳定性好.性能优良等优点,开源数据库在中低端应用上占据了很大的市场份额,而 MySQL 正是开源数据库中的杰出代表.MySQL 数据库 ...

  5. mysql2已经存在数据数据导入,在MYSQL中导入已存在的数据库

    MYSQL似乎很好玩,有一次看见一个同学神速般地创建一个数据量庞大的数据库,当时没搞清楚是什么回事.后来我重装MYSQL,得自己重新建数据库, 我一头雾水,这么多字段,肯定不是一个一个输入字段,再请教 ...

  6. mysql 中存储引擎是什么意思_mysql常用的存储引擎是什么

    mysql常用的存储引擎是什么 发布时间:2020-12-02 09:35:04 来源:亿速云 阅读:62 作者:小新 这篇文章将为大家详细讲解有关mysql常用的存储引擎是什么,小编觉得挺实用的,因 ...

  7. mysql中if在oracle怎么用_MySql和Oracle的使用

    本文档是一个记录文档,会不定时更新使用过程中遇到的差异问题 本文档记录MySql和Oracle在使用中要注意的问题,也包括两者使用上的差异问题 字符串拼接函数 CONCAT MySql MySql的 ...

  8. mysql中数据定义和数据控制语言_MySQL 数据定义语言(DDL)

    SQL 包含以下 4部分:1数据定义语言(DDL):DROP.CREATE.ALTER 等语句.2数据操作语言(DML):INSERT(插入).UPDATE(修改).DELETE(删除)语句.3数据查 ...

  9. SQL Server和MysQL中的联表更新sql示例

    目录 需求说明 SQL Server中联表更新sql示例 MySQL中联表更新sql示例 需求说明 需求说明:把表B的报名号数据,更新到另一张表A的报名号列.通过表A证件号码和表B身份证号相等. SQ ...

最新文章

  1. 数据防泄漏(中文版)
  2. java final
  3. PullToRefreshListView下拉刷新与上拉载入
  4. 2018-06-25-Python全栈开发day21-part2-time模块介绍
  5. 哈哈,我的Blog开通了。。。
  6. 数据结构 | 实现串(定长顺序存储表示法)
  7. Redis实现消息队列和订阅发布模式
  8. 最难面试的IT公司之ThoughtWorks代码挑战——FizzBuzzWhizz游戏(C#解法)
  9. Tensorflow GAN对抗生成网络实战
  10. cygwin中如何使用gcc
  11. 基于Java毕业设计在线购书商城系统源码+系统+mysql+lw文档+部署软件
  12. Mcafee之我见 * 一个木马引发的“麦咖啡”
  13. win11如何设置空间音效 windows11设置空间音效的步骤方法
  14. Kanzi Shader入门
  15. 晒一晒程序员桌面,你惊呆了没?
  16. 如果能理解医生的准确意图,深度学习会是医疗诊断的未来吗?
  17. ceph monitor paxos算法
  18. 如何扛住 100 亿次请求?
  19. iOS各个版本的特性和差别
  20. 5000台机器的网吧配置

热门文章

  1. 6000万条GitHub帖子告诉你:工作状态与表情符号强相关
  2. 漫画:这份程序员自画像,是不是你的?
  3. 让Python在后台自动解压各种压缩文件!
  4. 10 行 Python 代码自动清理电脑内重复文件,解放双手!
  5. 程序员,别再无脑刷题了,这样学 Python,编程能力暴增!
  6. 阿里文娱实战 | 小而美的 egg-react-ssr 开源实现方案
  7. 如何快速打通 Docker 镜像发布流程?
  8. 深度学习专项课程精炼图笔记!必备收藏 | 原力计划
  9. 程序员都应该了解的一种数据格式之 JSON
  10. 程序员都应了解的 CDN 是什么?