写在前面
已经不记得上次写sql存储过程是什么时候的事情了,虽然说用ORM或配合注解加sql语句来访问数据库在研发效率和维护调试的便利性上绝对甩存储过程几条街;但是在做一些简单的数据整理和维护操作时,直接使用存储过程来实现还是更方便的;以下代码的功能是重置关卡表的主键字段,使其从1开始重新递增排列,并重置自增变量,用到了游标和主键约束的增删操作以及动态sql语句的执行,值得做个记录备忘。
代码实现
CREATE PROCEDURE `resetFcMapLevelIds`()
BEGIN
DECLARE var_level_id int(8);
DECLARE var_user varchar(255);
DECLARE var_game_group int(8);
DECLARE var_map_desc varchar(255);
DECLARE var_game_data text;
DECLARE var_id int;
DECLARE var_new_level_id int(8);
DECLARE count int(8);
declare i int(8);
-- 创建结束标志变量
DECLARE done INT DEFAULT false;
declare cc cursor for select `user`, game_group,map_desc, game_data, level_id FROM fc_map_level ORDER BY level_id ASC;
-- 指定游标循环结束时的返回值
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;
ALTER TABLE fc_map_level MODIFY id INT;
ALTER TABLE fc_map_level DROP PRIMARY KEY;
open cc;
set i = 0;
WHILE not done DO
FETCH cc INTO var_user, var_game_group, var_map_desc, var_game_data, var_level_id;
SET i = i + 1;
UPDATE fc_map_level SET id = i WHERE level_id = var_level_id;
END WHILE;
SELECT i;
close cc;
ALTER TABLE fc_map_level ADD PRIMARY KEY (id);
ALTER TABLE fc_map_level MODIFY id INT AUTO_INCREMENT;
set i = i + 1;
set @sql = concat('ALTER TABLE fc_map_level AUTO_INCREMENT=', i);
prepare st from @sql;
execute st;
END
调用方式示意:
CALL procedure_name(argument1, argument2, ...);
总结
使用SQL来实现还是非常直接和高效的,省去了客户端频繁调用的网络开销,如果MySql中有大批量的内联数据操作场景,使用存储过程依然是最好的解决方案。