今天在工作的时候,遇到一个需求。
需要去把一个字段(原本是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