Mysql游标循环遍历
来源:互联网 发布:爱丁堡商学院申请 知乎 编辑:程序博客网 时间:2024/05/19 08:04
在大型的数据面前修改表内的内容,使用Mysql的游标实现
牧牛遛马根据在存储过程的接触上实际的使用过程在代码的每个逻辑后面加上注释来大致实现一下遍历数据表的逻辑
牧牛遛马
踩过的雷区:
1、记不得游标的查询单词————–fetch
2、设置循环条件的代码写错————
declare continue handler for not found set flag = false;
漏写for,handler错写成handle
3、游标查询的时候要赋值给多个变量,加逗号就可以了
fetch liuma into lmage,lmname;
不能理解liuma里面有多条字段信息数据错误。
4、until 语句后面不能加逗号
正确———–until flag = false
错误———–until flag = false;
5、变量在游标或者handler的后面定义报错:
ERROR 1337 (42000): Variable or condition declaration after cursor or handler de
claration
Surfing the code…
提个需求:
更改表中的所有数据,规则如下
{
如果年龄大于18,名字后面加上说自己是成年人;
如果年龄小于18,名字后面加上说自己是未成年人;
}
1、先来一张表
这里便于演示,只显示了七条数据,根据实现的思想逻辑可以扩展到百万数据的更新。
mysql> select * from emp;+----+--------+------+---------+| id | name | age | dept_in |+----+--------+------+---------+| 1 | 张三 | 18 | 1 || 2 | 李四 | 18 | 1 || 3 | 王五 | 20 | 1 || 4 | 赵六 | 21 | 2 || 5 | 小强 | 12 | 3 || 6 | 大锤 | 12 | 3 || 7 | 中申通 | 23 | 3 |+----+--------+------+---------+7 rows in set (0.00 sec)
2、写一下游标遍历数据的代码
mysql> delimiter $$mysql> create procedure muniu () -> begin -> declare lmage int(11); -> declare lmname varchar(50); -> declare flag int default true;#声明一个开关变量flag用于循环结束判断默认是true; -> declare liuma cursor for(select age,name from emp);#申明一个游标,名字叫liuma,因为游标指向的表内有两个字段,需要两个变量存储,所有得申明两个变量; -> -> declare continue handler for not found set flag = false; -> open liuma;#打开游标 -> -> repeat -> fetch liuma into lmage,lmname;#把游标的内容赋值到变量中。 -> if(lmage<18) -> then update emp set name = concat(lmname,"说我是未成年人,读书少") where age = lmage; -> elseif(lmage>18 or lmage = 18) -> then update emp set name = concat(lmname,"说我是成年人,不会乱来") where age = lmage; -> end if; -> until flag = false -> end repeat; -> close liuma;#关闭游标 -> end$$Query OK, 0 rows affected (0.00 sec)mysql> delimiter ;mysql>mysql>mysql>mysql> call muniu;Query OK, 0 rows affected (0.51 sec)mysql> select * from emp;+----+------------------------------+------+---------+| id | name | age | dept_in |+----+------------------------------+------+---------+| 1 | 李四说我是成年人,不会乱来 | 18 | 1 || 2 | 李四说我是成年人,不会乱来 | 18 | 1 || 3 | 王五说我是成年人,不会乱来 | 20 | 1 || 4 | 赵六说我是成年人,不会乱来 | 21 | 2 || 5 | 大锤说我是未成年人,读书少 | 12 | 3 || 6 | 大锤说我是未成年人,读书少 | 12 | 3 || 7 | 中申通说我是成年人,不会乱来 | 23 | 3 |+----+------------------------------+------+---------+7 rows in set (0.00 sec)
从上面的代码运行中我们发现,当age重复的时候,他们的名字会出现错误,第一条应该是张三说,可是运行出来是李四说,第5条应该是小强说,运行出来是大锤说。
这是因为我们在查询的时候使用的是age字段,每次更新数据的时候会把age相同的一起更新,第二次把第一次覆盖导致。
要解决这个问题,需要在游标中传入一个主键参数,然后根据主键做条件,根据age做判断就可以解决。这里就先把数据更新为不重复数据,模拟age为主键的情况进行演示一下:
先更新一下数据
mysql> update emp set name = "张三" where id =1;Query OK, 1 row affected (0.07 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set age = 13 where id =1;Query OK, 1 row affected (0.07 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "李四" where id= 2;Query OK, 1 row affected (0.04 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "王五" where id= 3;Query OK, 1 row affected (0.05 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "赵六" where id= 4;Query OK, 1 row affected (0.04 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "小强" where id= 5;Query OK, 1 row affected (0.05 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "大锤" where id= 6;Query OK, 1 row affected (0.04 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set age=11 where id= 6;Query OK, 1 row affected (0.07 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "中申通" where id= 7;Query OK, 1 row affected (0.11 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> select * from emp;+----+--------+------+---------+| id | name | age | dept_in |+----+--------+------+---------+| 1 | 张三 | 13 | 1 || 2 | 李四 | 18 | 1 || 3 | 王五 | 20 | 1 || 4 | 赵六 | 21 | 2 || 5 | 小强 | 12 | 3 || 6 | 大锤 | 11 | 3 || 7 | 中申通 | 23 | 3 |+----+--------+------+---------+7 rows in set (0.00 sec)
再运行一下游标过程存储:
mysql> delimiter $$mysql> create procedure muniu () -> begin -> declare lmage int(11); -> declare lmname varchar(50); -> declare flag int default true; -> declare liuma cursor for select age,name from emp; -> -> declare continue handler for not found set flag = false; -> open liuma; -> repeat -> fetch liuma into lmage,lmname; -> if(lmage<18) -> then update emp set name = concat(lmname,"说我是未成年人,读书少") -> -> where age = lmage; -> else -> update emp set name = concat(lmname,"说我是成年人,不会乱来") where -> -> age = lmage; -> end if; -> -> until flag = false -> end repeat; -> close liuma; -> end$$Query OK, 0 rows affected (0.00 sec)mysql> delimiter ;mysql>mysql> call muniu;Query OK, 0 rows affected (0.43 sec)mysql> select * from emp;+----+------------------------------+------+---------+| id | name | age | dept_in |+----+------------------------------+------+---------+| 1 | 张三说我是未成年人,读书少 | 13 | 1 || 2 | 李四说我是成年人,不会乱来 | 18 | 1 || 3 | 王五说我是成年人,不会乱来 | 20 | 1 || 4 | 赵六说我是成年人,不会乱来 | 21 | 2 || 5 | 小强说我是未成年人,读书少 | 12 | 3 || 6 | 大锤说我是未成年人,读书少 | 11 | 3 || 7 | 中申通说我是成年人,不会乱来 | 23 | 3 |+----+------------------------------+------+---------+7 rows in set (0.00 sec)
- Mysql游标循环遍历
- mysql里怎样循环遍历游标
- mysql 遍历游标 处理
- Mysql游标遍历
- MySQL 游标遍历
- Mysql游标和循环
- MySQL游标循环示例
- MySQL游标循环
- MySQL 游标 循环
- MYSQL游标循环
- mysql 游标循环
- mysql游标嵌套循环
- mysql游标嵌套循环
- Oracle 遍历游标循环更新
- MYSQL游标嵌套循环 动态游标
- mysql存储过程查询结果循环遍历 判断 赋值 游标等基本操作
- mysql存储过程查询结果循环遍历 判断 赋值 游标等基本操作
- mysql存储过程查询结果循环遍历 判断 赋值 游标等基本操作
- 数据类型
- 【bzoj3196】Tyvj 1730 二逼平衡树
- ARM基础学习-寄存器寻址方式和指令
- JAVA多线程断点下载
- 山东科技大学联合集训赛问题 G: 数字逻辑练习题
- Mysql游标循环遍历
- IPV6的地址
- win下安装scrapy框架
- 我的java学习路之循环学习应用demo1九九乘法表
- matlab中创建一维数组变量的方法
- struts2+jquery+ajax实现传输List数据并解析
- java中讲讲FileInputStream的用法,举例?
- JavaScript中常用的DOM操作函数
- 【leetcode】binary-tree-postorder-traversal