今天在写存储过程,想要测试一些东西,其中有一个表,需要插入100万用户,每个用户有40行记录,这里面有两个循环,想到了嵌套。

一般大家都知道for循环的嵌套,但是mysql存储过程中只有三种循环while、repeat、loop。因为一直使用while,所以就打算用while来做这件事情。结果发现,总是不能够循环,直插入一个用户的40行记录,非常无语。代码如下:

 

 
  
  1. DELIMITER $$ 
  2.  
  3. USE `qqfs_db_items`$$ 
  4.  
  5. DROP PROCEDURE IF EXISTS `qqsf_proc_InsertItemTest`$$ 
  6.  
  7. CREATE  PROCEDURE `qqsf_proc_InsertItemTest`( 
  8.  i_PlayerCount INT) COMMENT '插入道具表测试' 
  9.  BEGIN 
  10.   DECLARE a INT DEFAULT 1; 
  11.   DECLARE b TINYINT DEFAULT 1; 
  12.   WHILE (a <= i_PlayerCount) DO 
  13.     
  14.    SET a = a + 1; 
  15.    WHILE (b <=40) DO 
  16.     INSERT INTO qqfs_tbl_items (AuthID,Slot,CID,GTID,Nums,Endtime,Flags,UseInfo) 
  17.     VALUES 
  18.     (a,b,0,0,1,NOW(),0,1); 
  19.     SET b = b + 1; 
  20.    END WHILE; 
  21.       END WHILE; 
  22.  END$$ 
  23.  
  24. DELIMITER ; 

后来用select a,select b,自定义查询断点发现循环是继续的。网上查了下,貌似没人说清楚。后来仔细一看,原来自己受了以前程序中for循环的束缚,以为b的值总是会在第二次循环时被重置,其实b的值在一次循环之后,就已经变为40了,所以,有两种解决方法,一个是想程序中for循环一样,将b的初始化放在a的循环中;另一种就是在a循环中,将b的值再次初始化为1.

问题得到解决,新代码如下:

 
  
  1. DELIMITER $$ 
  2.  
  3. USE `qqfs_db_items`$$ 
  4.  
  5. DROP PROCEDURE IF EXISTS `qqsf_proc_InsertItemTest`$$ 
  6.  
  7. CREATE DEFINER=`root`@`%` PROCEDURE `qqsf_proc_InsertItemTest`( 
  8.  i_PlayerCount INT) COMMENT '插入道具表测试' 
  9.  BEGIN 
  10.   DECLARE a INT DEFAULT 1; 
  11.   DECLARE b TINYINT DEFAULT 1; 
  12.   WHILE (a <= i_PlayerCount) DO 
  13.   -- repeat 
  14.     
  15.     
  16.    SET a = a + 1; 
  17.    -- select a; 
  18.    WHILE (b <=40) DO 
  19.     INSERT INTO qqfs_tbl_items (AuthID,Slot,CID,GTID,Nums,Endtime,Flags,UseInfo) 
  20.     VALUES 
  21.     (a,b,0,0,1,NOW(),0,1); 
  22.     SET b = b + 1; 
  23.     -- select b; 
  24.    END WHILE; 
  25.     
  26.    SET b = 1; 
  27.    -- select a; 
  28.    -- until a >= i_PlayerCount 
  29.   -- end repeat; 
  30.    END WHILE; 
  31.  END$$ 
  32.  
  33. DELIMITER ; 

包含了repeat的实现和我在排错中给a和b打的select断点。希望对大家有用。