工作中遇到的问题,先记录一下,方便以后查看
存在两张表,user表和friend表
user表部分字段,如上图
friend表部分字段,如上图
往friend表插入千条数据,friend表中的userId值是固定的,对应的friendId是从user表中获取
实现方案:
1、游标存储:
-- 在windows系统中写存储过程时,如果需要使用declare声明变量,需要添加这个关键字,否则会报错。 delimiter // drop procedure if exists insertUserFriend;CREATE PROCEDURE insertUserFriend(id int, idx int, size int)BEGIN -- 创建接收游标数据的变量 declare c int; -- 创建结束标志变量 declare done int default FALSE; -- 创建游标 declare cur cursor for select userId from u_user where userId != id LIMIT idx, size; -- 指定游标循环结束时的返回值 declare continue HANDLER for not found set done = TRUE; -- 打开游标 open cur; -- 开始循环游标里的数据 read_loop:loop -- 根据游标当前指向的一条数据 fetch cur into c; -- 判断游标的循环是否结束 if done then leave read_loop; -- 跳出游标循环 end if; INSERT INTO u_user_friend (userId, friendId, createTime, lastExchangeTime) VALUES (id, c, NOW(), NOW()); -- 结束游标循环 end loop; -- 关闭游标 close cur; -- 输出结果 select * from u_user_friend WHERE userId = id; END; //-- 调用位置修改值就可以,不用重建存储过程CALL insertUserFriend(7071, 0, 5082);
2、while循环---待测试
DELIMITER;//create procedure myproc()begindeclare num int;declare num1 int;DECLARE oldUserId int;DECLARE newUserId int;DECLARE isExist int;-- 用于验证是否存在好友关系set num=1;set num1=1;set oldUserId=0;set newUserId=0;set isExist=0;while num <= 100 do select min(userId) into oldUserId from u_user where userId>oldUserId; set num1=1; while num1 <= 1000 do set newUserId=newUserId+1; select min(userId) into newUserId from u_user where userId>newUserId; if (newUserId>0 and oldUserId>0) THEN select count(userId) into isExist from u_user_friend where (userId=oldUserId and friendId=newUserId) or (userId=newUserId and friendId=oldUserId); if(isExist=0) THEN INSERT INTO `u_user_friend` (`userId`, `friendId`, `memo`, `des`, `img`, `mps`, `black`, `createTime`, `blackTime`, `lastExchangeTime`) VALUES (oldUserId, newUserId, NULL, NULL, NULL, NULL, b'0', NOW(), NOW(), NOW()); END IF; END IF; set num1=num1+1; set isExist=0; end while; set oldUserId=oldUserId+1; set num=num+1;end while;commit;end;//-- 执行存储过程CALL myproc();-- 删除存储过程-- drop PROCEDURE myproc-- 清空u_user_friend里面的所有数据(慎用)-- truncate table u_user_friend
附:
delimiter的作用:告诉解释器,这段命令是否已经结束了,mysql是否可以执行了
默认情况下,delimiter是‘;’但是当我们编写procedure时,如果是默认设置,那么一遇到‘;’,mysql就要执行,这是我们不希望看到的