MySql 循环执行语句,循环执行update,详细介绍【游标嵌套】

今天在工作的时候,遇到一个需求。

    需要去把一个字段(原本是uuid),改成00001,00002,这样的格式。如果是数据比较少当然无所谓了,但是表里面有上千条数据,这个时候再去手动修改就不科学了。

 

本能的想到了for循环去执行,然后老大丢了一个sql过来,一下子蒙蔽了,后来在其讲解的条件下懂了,本着好东西不私藏道理在这里分享出来。

 

BEGIN
	/*下面这三行就是相当于定义变量   变量名,变量类型,默认值 */
 declare  no_more_record int DEFAULT 0;
 DECLARE  x int;
 DECLARE  x1 VARCHAR(100);
 DECLARE  akey varchar(100);
	/*首先这里对游标进行定义*/
	/*cur_record 也是一个随便取的名字 */
 DECLARE  cur_record CURSOR FOR  SELECT supplier_key from equi_supplier;  	
 /*这个是个条件处理,针对NOT FOUND的条件,当没有记录时赋值为1*/
	/* 判断上面你写的 查询语句是否有返回的数据 */
 DECLARE  CONTINUE HANDLER FOR NOT FOUND  SET  no_more_record = 1;
 /*接着使用OPEN打开游标*/
 OPEN  cur_record; 
/*把第一行数据写入变量中,游标也随之指向了记录的第一行*/
/* 这里就相当于把上面的你写的select查询的查询结果第一条赋值给akey这个变量 */
 FETCH  cur_record INTO akey; 
/* 这个相当于一个赋值*/
set x=0;
/* 这里是一个循环判断 */
 WHILE no_more_record != 1 DO
	set x=x+1;
	/* CAST(x AS CHAR)  把 int 类型的x 转成 CHAR */
	/* CONCAT('000000',CAST(x AS CHAR)) 联合字符串再 00000后面追加x */
	/* RIGHT(CONCAT('000000',CAST(x AS CHAR)),5)   去前面字符串的前5位 */
	set x1=RIGHT(CONCAT('000000',CAST(x AS CHAR)),5);
	/* 你所要循环执行的语句 */
	update equi_supplier set supplier_no=x1 where supplier_key = akey;
	/* 一次循环结束再次取出下一个游标值 */
	FETCH  cur_record INTO akey;
 END WHILE;
/*用完后记得用CLOSE把资源释放掉*/
 CLOSE  cur_record;  
select 0;
END

最后运用,我这里以navicat为例

 

 

然后直接像你平时运行sql一样去运行     call aa();   这里的 aa 就是我刚刚保存的名字

 

代码全部的涵义已经写出来了,当然这是一个简单的逻辑。如果你还有其它需求,可以自行增加代码

 

 

今天又遇到一个新的需求(更新)

需要给表中一级数据添加编号   0001,给表中二级数据添加编号 0001001,给表中三级数据添加编号 00001001001。

 

给一级数据添加编号就是上面的那个,主要是二级三级比较复杂。需要用到游标嵌套

找了半天的相关文章,代码都乱七八糟的,很难的去看懂,为了代码的简洁我就不写注释了(注释在上一个函数里面全部都写的很清楚了)

修改二级分类为00001001格式

BEGIN
	declare  no_more_record int DEFAULT 0;
	DECLARE  x1 VARCHAR(100);
	DECLARE  key_1 varchar(100);

	DECLARE  equi_dict_1 CURSOR FOR  SELECT dict_key,dict_no from equi_dict WHERE dict_lvl = 1;  	
	DECLARE  CONTINUE HANDLER FOR NOT FOUND  SET  no_more_record = 1;

	OPEN  equi_dict_1; 
	FETCH  equi_dict_1 INTO key_1,x1; 
	WHILE no_more_record != 1 DO
				
		BEGIN
			declare  no_more_record_2 int DEFAULT 0;
			DECLARE  x int;
			DECLARE  x2 VARCHAR(100); 
			DECLARE  key_2 varchar(100);

			DECLARE  equi_dict_2 CURSOR FOR  SELECT dict_key from equi_dict WHERE prod_name_key = key_1; 
			DECLARE  CONTINUE HANDLER FOR NOT FOUND  SET  no_more_record_2 = 1;

			OPEN equi_dict_2;			
			FETCH equi_dict_2 INTO key_2;
			set x=0;
			WHILE no_more_record_2 != 1 DO
				set x=x+1;
				set x2=RIGHT(CONCAT('00',CAST(x AS CHAR)),3);
				set x2=CONCAT(x1,x2);
				update equi_dict set dict_no=x2 where dict_key = key_2 AND dict_lvl = 2;
				FETCH equi_dict_2 INTO key_2;

			END WHILE;
		  CLOSE  equi_dict_2;  
		END;

		FETCH  equi_dict_1 INTO key_1,x1; 
	END WHILE;
	CLOSE  equi_dict_1;  
	select 0;
END

修改三级分类为00001001001格式

BEGIN
 declare  no_more_record int DEFAULT 0;
 DECLARE  x1 VARCHAR(100);
 DECLARE  key_1 varchar(100);

 DECLARE  equi_dict_1 CURSOR FOR  SELECT dict_key,dict_no from equi_dict WHERE dict_lvl = 2;  	
 DECLARE  CONTINUE HANDLER FOR NOT FOUND  SET  no_more_record = 1;

 OPEN  equi_dict_1; 
 FETCH  equi_dict_1 INTO key_1,x1; 
 WHILE no_more_record != 1 DO

		BEGIN
			declare  no_more_record_2 int DEFAULT 0;
			DECLARE  x int;
			DECLARE  x2 VARCHAR(100); 
			DECLARE  key_2 varchar(100);

			DECLARE  equi_dict_2 CURSOR FOR  SELECT dict_key from equi_dict WHERE prod_mfr_key = key_1 AND dict_lvl = 3;
			DECLARE  CONTINUE HANDLER FOR NOT FOUND  SET  no_more_record_2 = 1;

			OPEN equi_dict_2;			
			FETCH equi_dict_2 INTO key_2;
			set x=0;
			WHILE no_more_record_2 != 1 DO

				set x=x+1;
				set x2=RIGHT(CONCAT('00',CAST(x AS CHAR)),3);
				set x2=CONCAT(x1,x2);
				update equi_dict set dict_no=x2 where dict_key = key_2;
				FETCH equi_dict_2 INTO key_2;

			END WHILE;
		  CLOSE  equi_dict_2;  
		END;

		FETCH  equi_dict_1 INTO key_1,x1; 
 END WHILE;
/*用完后记得用CLOSE把资源释放掉*/
 CLOSE  equi_dict_1;  
select 0;
END

 

 

 

 

 

 

全部评论

相关推荐

03-15 14:55
已编辑
门头沟学院 golang
bg:双非学院本 ACM银 go选手timeline:3.1号开始暑期投递3.7号第二家公司离职顽岩科技 ai服务中台方向 笔试➕两轮面试,二面挂(钱真的好多😭)厦门纳克希科技 搞AI的,一面OC猎豹移动 搞AIGC方向 一面OC北京七牛云 搞AI接口方向 一面OC上海古德猫宁 搞AIGC方向 二面OC上海简文 面试撞了直接拒深圳图灵 搞AIGC方向一面后无消息懒得问了,面试官当场反馈不错其他小厂没记,通过率80%,小厂杀手😂北京字节 具体业务不方便透露也是AIGC后端方向2.28约面 (不知道怎么捞的我,我也没在别的地方投过字节简历哇)3.6一面 一小时 半小时拷打简历(主要是AIGC部分)剩余半小时两个看代码猜结果(经典go问题)➕合并二叉树(秒a,但是造case造了10分钟哈哈)一天后约二面3.12 二面,让我挑简历上两个亮点说,主要说的docker容器生命周期管理和raft协议使用二分法优化新任leader上任后与follower同步时间。跟面试官有共鸣,面试官还问我docker底层cpu隔离原理和是否知道虚拟显存。之后一道easy算法,(o1空间解决 给定字符串含有{和}是否合法)秒a,之后进阶版如何用10台机加快构建,想五分钟后a出来。面试官以为45分钟面试时间,留了18分钟让我跟他随便聊,后面考了linux top和free的部分数据说什么意思(专业对口了只能说,但是当时没答很好)。因为当时手里有7牛云offer,跟面试官说能否快点面试,马上另外一家时间到了。10分钟后约hr面3.13,上午hr面,下午走完流程offer到手3.14腾讯技术运营约面,想直接拒😂感受: 因为有AIGC经验所以特别受AI初创公司青睐,AIGC后端感觉竞争很小(指今年),全是简历拷打,基本没有人问我八股(八股吟唱被打断.jpeg),学的东西比较广的同时也能纵向深挖学习,也运气比较好了哈哈可能出于性格原因,没有走主流Java路线,也没有去主动跟着课写项目,项目都是自己研究和写的哈哈
烤点老白薯:你根本不是典型学院本的那种人,贵了你这能力
查看7道真题和解析
点赞 评论 收藏
分享
03-15 00:45
已编辑
中国科学院大学 Java
问的很简单都秒了,但是面试官没开摄像头,疑似kpi,无后续。--------------------3/14更新,3/12通知给了口头offer,3/13发了意向书,已拒。一面(35min)(25/3/6)(无后续)    1、自我介绍    2、介绍一下你的那个Python相关项目(本科毕设,web系统+算法模型提供部分接口)    3、Java面向对象有哪些特点呢?详细说一下。    4、介绍一下hashmap;为什么要把链表转换为红黑树呢?红黑树查找的时间复杂度?1.7和1.8的区别。    5、介绍一下concurrentHashmap。    6、synchronized锁和Lock锁有什么区别?    7、公平锁的一个底层是怎么实现的呢?    8、线程池的核心参数、拒绝策略、提交一个任务执行流程?    9、spring有哪些特点?(ioc/aop)    10、spring中对于循环依赖是怎么解决的?    11、MySQL和redis的区别?    12、MySQL的索引结构是什么?    13、MySQL的事务有哪些特性?怎么保证?    14、MySQL的默认隔离级别?可重复读是怎么做到的呢?    15、介绍一下MVCC和快照读readview。    16、一般在什么场景下会使用redis?    17、对于大量的请求,如果此时缓存中还没有写入数据怎么办?    18、介绍一下redis实现的分布式锁。    19、有用过es和mongo DB吗?(知道,没用过)    20、消息中间件用过吗?说一下你的使用场景?    21、一个场景,如果说有一个接口响应的比较慢,如果说让你排查,你会怎么去排查?(上下游接口、大key问题,只答了两,后面试官补充)    无手撕,反问业务。
胖墩墩的查理在学c语言:哥们我是五号面的 流程差不多
查看21道真题和解析
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务