背景:近来总有玩家反馈少领取奖励的情形,所有待发奖励的玩家被汇总到某张的表的字段中,通过查询历史数据,发现在
insert到表时,数据有可能被截取啦,mysql没有设置sql_mode,没有错误或警告日志可以查询,同时,存放数据字段类型text,不
管怎样,也许是数据太长导致,故开发同学,要求DB段写个sp,按照每行1w数据行,分多行存放玩家数据,以免后续再
次可能发生。
表A:
Role_Id
11111
2222
3333
4444
5555
......
.....
表B:.
转换成:
id
1 1111,2222,3333....
2 444,55555,.....
如下通过游标方式实现转换过程:
CREATE TABLE B (
`Id` int(11) NOT NULL AUTO_INCREMENT COMMENT '流水Id',
`Role_Id` VARCHAR(8000),
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=xxx';
DROP PROCEDURE IF EXISTS sp_test_rows;
CREATE PROCEDURE ` sp_test_rows`()
BEGIN
DECLARE i INT; #一行多少字符关联
DECLARE vRoleId INT; #临时存放游标中roleid
DECLARE tRoleId VARCHAR(8000);#临时存放insert到中间表中的字符串
DECLARE done INT;
DECLARE cur CURSOR FOR SELECT Role_Id FROM A; #游标遍历数据
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
SET i=0;
OPEN cur;
label_loop:LOOP
SET i=i+1;
FETCH cur INTO vRoleId;
IF done THEN
LEAVE label_loop;
END IF;
SET tRoleId=CONCAT_WS(',',tRoleId,vRoleId);
IF MOD(i,1000)=0 THEN #一行中有1k字符保存表中;
INSERT INTO B(Role_Id) SELECT tRoleId; #开始存放转换数据行;
SET tRoleId=NULL;
END IF;
END LOOP label_loop;
CLOSE cur;
IF tRoleId IS NULL then
select '';
ELSE
INSERT INTO B(Role_Id) SELECT tRoleId;#存放超过1k之后,数据行
END IF;
END;
call sp_test_rows();
方法有些啰嗦,若有其他方法,还请分享下,^_^