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

 

 

 

 

 

 

### 回答1: MySQL 中的游标可以嵌套循环使用,实现比较复杂的数据处理逻辑。下面是一个简单的示例: ``` DECLARE cur1 CURSOR FOR SELECT id FROM table1; DECLARE cur2 CURSOR FOR SELECT value FROM table2 WHERE table1_id = @id; OPEN cur1; FETCH cur1 INTO @id; WHILE @@FETCH_STATUS = 0 DO OPEN cur2; FETCH cur2 INTO @value; WHILE @@FETCH_STATUS = 0 DO -- do something with @id and @value FETCH cur2 INTO @value; END WHILE; CLOSE cur2; FETCH cur1 INTO @id; END WHILE; CLOSE cur1; ``` 上面的代码中,先声明了两个游标 `cur1` 和 `cur2`,分别用于遍历表 `table1` 和表 `table2`。在第一个游标中,使用 `FETCH` 语句获取 `id`,并将其赋值给变量 `@id`。然后在 `WHILE` 循环中,检查 `@@FETCH_STATUS` 是否为 0,即是否还有数据可以获取。如果有,进入第二个游标循环,使用 `@id` 来过滤 `table2` 中的数据,并使用 `FETCH` 语句获取 `value`,并将其赋值给变量 `@value`。在第二个游标循环中,同样检查 `@@FETCH_STATUS` 是否为 0,如果有,就可以对 `@id` 和 `@value` 进行处理。最后,关闭 `cur2` 游标,继续在第一个游标中获取下一个 `id`,直到所有数据都处理完毕。 需要注意的是,在使用游标嵌套循环时,要尽量避免使用过多的嵌套,以避免性能问题。同时,也要注意游标的使用方式,确保在使用完毕后及时关闭游标,以释放资源。 ### 回答2: MySQL中的游标是一种用于遍历查询结果集的机制。游标嵌套循环是指在一个循环嵌套另一个循环,并使用游标来控制内部循环的遍历过程。 在MySQL中,可以通过以下步骤来实现游标嵌套循环: 1. 声明外部循环游标:首先,需要声明一个外部循环游标,用于遍历外部查询的结果集。 2. 打开外部循环游标:在开始外部循环之前,需要使用OPEN语句打开外部游标,准备开始遍历外部结果集。 3. 声明内部循环游标:在外部循环内部,需要声明一个内部循环游标,用于遍历内部查询的结果集。 4. 打开内部循环游标:在开始内部循环之前,需要使用OPEN语句打开内部游标,准备开始遍历内部结果集。 5. 循环遍历内部结果集:在内部循环中使用FETCH语句来从内部游标中获取一行结果,并进行相应的处理。 6. 关闭内部循环游标:在内部循环结束后,使用CLOSE语句来关闭内部游标,释放资源。 7. 关闭外部循环游标:在外部循环结束后,使用CLOSE语句来关闭外部游标,释放资源。 通过以上步骤,可以实现游标嵌套循环的功能。在嵌套循环中,外部循环的每一次迭代都会执行内部循环的全部迭代,直到外部循环结束。这种方法可以用于处理需要对多个结果集进行复杂操作的情况,提供了一种灵活的查询和处理方式。 需要注意的是,游标嵌套循环可能会导致性能问题,特别是在处理大数据量时。因此,在使用游标嵌套循环时,应谨慎使用,并根据实际情况考虑其他更高效的处理方式。 ### 回答3: MySQL中的游标嵌套循环是指在一个游标内部嵌套了另一个游标,并通过循环来处理嵌套游标游标是一种数据库对象,用于从查询结果中逐行获取数据。在MySQL中,使用游标需要以下步骤: 1. 声明并定义游标:通过DECLARE语句来声明和定义游标,可以指定游标的名称、查询语句和其他属性。 2. 打开游标:使用OPEN语句来打开游标,使其准备好获取数据。 3. 循环获取数据:使用FETCH语句来逐行获取游标所指向的查询结果数据。可以通过循环的方式获取所有数据或者仅获取所需的数据。 4. 关闭游标:使用CLOSE语句来关闭游标,释放资源。 在游标嵌套循环中,内层游标的查询依赖于外层游标的结果。嵌套循环的步骤如下: 1. 声明并定义外层游标。 2. 打开外层游标。 3. 循环获取外层游标的数据。 4. 在外层循环中,声明并定义内层游标,并将内层游标的查询条件绑定到外层游标的数据。 5. 打开内层游标。 6. 循环获取内层游标的数据。 7. 关闭内层游标。 8. 关闭外层游标。 通过游标嵌套循环可以在多个数据集之间进行关联操作。对于每个外层数据,内层循环可以获取相关的数据进行处理。嵌套循环可以用于完成复杂的数据处理和逻辑操作,但是需要注意效率和性能的问题,因为每次循环都需要执行数据库操作,可能会导致性能下降。 总之,MySQL中的游标嵌套循环是一种处理复杂数据操作的方法,通过嵌套的方式将多个数据集关联起来,可以提高数据处理的灵活性和精确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值