使用存储过程插入100行随机的记录,怎么老出现重复的值?

everygoog 2014-08-28 01:39:12
老师布置了一个作业,要求用Mysql实现需求
有一个用户表,有id,用户的真实名字,年龄。
通过一段存储过程来实现向表里插入100数据,其中年龄随机
姓名
姓氏:’赵钱孙李周吴郑王’;,随机取出一个
名字:’一段文字字符串’,随机的取出一个字或者两个字


然后我写出的代码如下:
-- 创建用户表,在project里
create table user1 (
id int not null primary key auto_increment,
name varchar(3) not null,
age tinyint not null
) charset utf8;

-- 创建存储过程
delimiter $$
create procedure pro3(num int)
begin
declare fname char(1);
declare name1 char(1);
declare name2 char(1);
declare fullname varchar(3);
declare age int;
declare i int default 1;

while i <=num do
set fname = substring('赵钱孙李周吴郑王',floor(1+8*rand()),1); -- 姓
set name1 = substring('一二三四五六七八九十甲乙丙丁',floor(1+14*rand()),1); -- 抽一个字
set name2 = substring('一二三四五六七八九十甲乙丙丁',floor(1+14*rand()),1); -- 抽一个字

if round(rand())=0 then -- 创造一个局部变量fullname代表全名,随机确定是两个字还是三个字
set fullname = concat(fname,name1);
end if;
if round(rand())=1 then
set fullname = concat(fname,name1,name2);
end if;

set age = floor(20+31*rand()); -- 年龄为20-50的随机

insert into user1 values(null,fullname,age); -- 插入数据

set i = i + 1;
end while;
end
$$
delimiter ;

call pro3(100); -- 执行过程


出现的结果出乎意料,出现了很多连续一样的姓名,执行结果如下:
mysql> select * from user1;
+-----+--------+-----+
| id | name | age |
+-----+--------+-----+
| 1 | 赵三 | 28 |
| 2 | 孙一四 | 50 |
| 3 | 郑丁九 | 42 |
| 4 | 王八 | 47 |
| 5 | 钱六 | 48 |
| 6 | 李五 | 26 |
| 7 | 李五 | 41 |
| 8 | 郑二三 | 22 |
| 9 | 孙七六 | 24 |
| 10 | 孙三 | 21 |
| 11 | 钱甲二 | 26 |
| 12 | 孙丙 | 42 |
| 13 | 孙丙 | 37 |
| 14 | 赵六丁 | 24 |
| 15 | 赵六丁 | 40 |
| 16 | 王十七 | 28 |
| 17 | 孙九 | 22 |
| 18 | 李二 | 23 |
| 19 | 李十 | 23 |
| 20 | 赵丁甲 | 50 |
| 21 | 钱一九 | 49 |
| 22 | 钱一九 | 22 |
| 23 | 钱一九 | 30 |
| 24 | 钱一九 | 30 |
| 25 | 孙五 | 46 |
| 26 | 吴三十 | 39 |
| 27 | 赵七二 | 50 |
| 28 | 赵七二 | 29 |
| 29 | 孙甲九 | 20 |
| 30 | 郑乙十 | 35 |
| 31 | 周一 | 50 |
| 32 | 吴甲七 | 50 |
| 33 | 李丁十 | 47 |
| 34 | 李丁十 | 29 |
| 35 | 李丁十 | 40 |
| 36 | 孙五 | 47 |
| 37 | 赵九丙 | 41 |
| 38 | 郑三八 | 43 |
| 39 | 钱七 | 37 |
| 40 | 钱二一 | 24 |
| 41 | 王七五 | 45 |
| 42 | 李十四 | 24 |
| 43 | 李十四 | 28 |
| 44 | 孙甲甲 | 49 |
| 45 | 郑五 | 38 |
| 46 | 赵甲 | 27 |
| 47 | 王三 | 39 |
| 48 | 王三 | 26 |
| 49 | 王三 | 22 |
| 50 | 王三 | 30 |
| 51 | 钱一九 | 44 |
| 52 | 赵四 | 30 |
| 53 | 王十九 | 50 |
| 54 | 王十九 | 34 |
| 55 | 王十九 | 40 |
| 56 | 周丙甲 | 20 |
| 57 | 孙十 | 47 |
| 58 | 王丙 | 32 |
| 59 | 王六 | 43 |
| 60 | 吴三甲 | 29 |
| 61 | 王乙 | 26 |
| 62 | 赵甲 | 46 |
| 63 | 赵甲 | 23 |
| 64 | 王八丙 | 25 |
| 65 | 王八丙 | 30 |
| 66 | 周乙六 | 50 |
| 67 | 吴五八 | 21 |
| 68 | 孙五 | 42 |
| 69 | 赵丙六 | 48 |
| 70 | 周三 | 48 |
| 71 | 周三 | 47 |
| 72 | 李乙 | 46 |
| 73 | 李乙 | 40 |
| 74 | 吴十五 | 45 |
| 75 | 赵十五 | 36 |
| 76 | 赵十五 | 25 |
| 77 | 李十 | 35 |
| 78 | 李甲 | 38 |
| 79 | 周三一 | 33 |
| 80 | 周三一 | 48 |
| 81 | 钱六六 | 33 |
| 82 | 钱六六 | 49 |
| 83 | 孙十六 | 36 |
| 84 | 王二甲 | 48 |
| 85 | 王二甲 | 39 |
| 86 | 王乙 | 30 |
| 87 | 郑三 | 21 |
| 88 | 赵二五 | 29 |
| 89 | 周丙丙 | 43 |
| 90 | 钱七乙 | 35 |
| 91 | 钱七乙 | 47 |
| 92 | 钱七乙 | 38 |
| 93 | 孙乙 | 29 |
| 94 | 周乙 | 32 |
| 95 | 郑乙十 | 46 |
| 96 | 郑乙十 | 37 |
| 97 | 吴八 | 46 |
| 98 | 吴十八 | 42 |
| 99 | 王乙四 | 30 |
| 100 | 吴九十 | 50 |


1.很奇怪的是,为什么有这么多连续重复的姓名啊,谁能帮忙解答下这个问题呢?

2.是否有更好的办法(必须是mysql+存储过程)去解决这个需求?求教。

3.我在mysql5.1的手册查询rand()函数看到:
-- 若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1))。
若要在7 到 12 的范围(包括7和12)内得到一个随机整数, 可使用以下语句:
SELECT FLOOR(7 + (RAND() * 6));

这种做法不会取到rand()=1导致超出范围?


...全文
124 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
九月茅桃 2014-08-28
  • 打赏
  • 举报
回复
执行效果如下:
mysql> DELIMITER $$
mysql> USE `test`$$
Database changed
mysql> DROP PROCEDURE IF EXISTS `pro3`$$
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CREATE  PROCEDURE `pro3`(num INT)
    -> BEGIN
    -> DECLARE fname CHAR(1);
    -> DECLARE name1 CHAR(1);
    -> DECLARE name2 CHAR(1);
    -> DECLARE fullname VARCHAR(3);
    -> DECLARE pre_fullname VARCHAR(3) DEFAULT '';
    -> DECLARE age INT;
    -> DECLARE i INT DEFAULT 1;
    -> WHILE i <=num DO
    -> SET fname = SUBSTRING('赵钱孙李周吴郑王',FLOOR(1+8*RAND()),1);  
    -> SET name1 = SUBSTRING('一二三四五六七八九十甲乙丙丁',ROUND(1+14*RAND()),1); 
    -> SET name2 = SUBSTRING('一二三四五六七八九十甲乙丙丁',ROUND(1+14*RAND()),1); 
    -> 
    -> IF ROUND(RAND())=0 THEN  
    -> SET fullname = CONCAT(fname,name1);
    -> END IF;
    -> IF ROUND(RAND())=1 THEN
    -> SET fullname = CONCAT(fname,name1,name2);
    -> END IF;
    -> 
    -> SET age = FLOOR(20+31*RAND());  
    -> /* 给临时变量赋值,看最新的一条记录的name值 */
    -> SELECT NAME INTO pre_fullname FROM user1 ORDER BY id DESC LIMIT 1;
    -> /* 开始判断,如果刚赋值的name跟上一次赋值的name值一样,就跳过,i保持不变,继续取值;否则i+1,继续循环取值*/
    -> IF fullname=pre_fullname AND i>1 THEN
    -> 
Display all 799 possibilities? (y or n) 
    -> SET i=i;
    -> ELSEIF fullname IS NULL THEN
    -> 
Display all 799 possibilities? (y or n) 
    -> SET i=i;
Display all 799 possibilities? (y or n) 
    -> SET i=i;
    -> ELSE
    -> 
Display all 799 possibilities? (y or n) 
    -> INSERT INTO user1 VALUES(NULL,fullname,age);  
    -> 
Display all 799 possibilities? (y or n) 
    -> SET i = i + 1; 
    -> END IF ;
    -> END WHILE;
    -> END$$
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;
mysql> 
mysql> truncate table user1;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from user1;
Empty set (0.00 sec)

mysql> call pro3(100);
Query OK, 1 row affected (0.11 sec)

mysql> select * from user1;
+-----+-----------+-----+
| id  | name      | age |
+-----+-----------+-----+
|   1 | 吴甲九    |  32 |
|   2 | 赵丙      |  49 |
|   3 | 钱二      |  40 |
|   4 | 郑二丙    |  34 |
|   5 | 孙四三    |  39 |
|   6 | 钱五十    |  39 |
|   7 | 赵五      |  23 |
|   8 | 郑九      |  22 |
|   9 | 钱九七    |  47 |
|  10 | 郑七乙    |  39 |
|  11 | 孙丙二    |  44 |
|  12 | 吴三九    |  30 |
|  13 | 钱九四    |  28 |
|  14 | 王十九    |  49 |
|  15 | 周丙乙    |  43 |
|  16 | 王十      |  33 |
|  17 | 钱乙七    |  36 |
|  18 | 赵七四    |  32 |
|  19 | 郑八二    |  31 |
|  20 | 赵二      |  35 |
|  21 | 赵丙      |  26 |
|  22 | 郑甲丁    |  38 |
|  23 | 周丙九    |  50 |
|  24 | 李丙五    |  27 |
|  25 | 李五三    |  37 |
|  26 | 孙丙六    |  46 |
|  27 | 钱八      |  37 |
|  28 | 周七六    |  40 |
|  29 | 李一一    |  45 |
|  30 | 钱十七    |  22 |
|  31 | 吴七一    |  49 |
|  32 | 吴丙六    |  39 |
|  33 | 吴四四    |  50 |
|  34 | 郑八丙    |  28 |
|  35 | 吴五七    |  26 |
|  36 | 吴甲      |  46 |
|  37 | 钱四      |  39 |
|  38 | 王丙九    |  24 |
|  39 | 王八八    |  38 |
|  40 | 吴乙丙    |  35 |
|  41 | 吴丙七    |  39 |
|  42 | 周甲丁    |  31 |
|  43 | 钱二甲    |  25 |
|  44 | 钱五丁    |  32 |
|  45 | 孙四二    |  28 |
|  46 | 李七丙    |  37 |
|  47 | 钱七七    |  46 |
|  48 | 郑乙四    |  33 |
|  49 | 钱甲丁    |  34 |
|  50 | 王五      |  37 |
|  51 | 吴一      |  44 |
|  52 | 王二十    |  33 |
|  53 | 郑四      |  41 |
|  54 | 钱九八    |  29 |
|  55 | 李十十    |  24 |
|  56 | 钱六七    |  44 |
|  57 | 王二      |  38 |
|  58 | 周五      |  36 |
|  59 | 吴九      |  44 |
|  60 | 赵丙      |  38 |
|  61 | 李五五    |  20 |
|  62 | 王八乙    |  33 |
|  63 | 王丙八    |  49 |
|  64 | 王九六    |  38 |
|  65 | 钱七      |  45 |
|  66 | 赵二二    |  36 |
|  67 | 钱五乙    |  40 |
|  68 | 孙甲七    |  43 |
|  69 | 郑甲五    |  47 |
|  70 | 赵丙      |  20 |
|  71 | 郑四      |  43 |
|  72 | 孙丙五    |  24 |
|  73 | 孙三      |  33 |
|  74 | 赵四乙    |  31 |
|  75 | 李        |  44 |
|  76 | 吴九丁    |  43 |
|  77 | 郑甲一    |  33 |
|  78 | 李三五    |  37 |
|  79 | 王二      |  31 |
|  80 | 赵七丙    |  35 |
|  81 | 吴三十    |  22 |
|  82 | 李二      |  50 |
|  83 | 李八      |  49 |
|  84 | 王一      |  27 |
|  85 | 王三      |  22 |
|  86 | 周五      |  45 |
|  87 | 郑八      |  44 |
|  88 | 郑甲二    |  48 |
|  89 | 赵乙      |  37 |
|  90 | 周四五    |  30 |
|  91 | 周二七    |  41 |
|  92 | 孙四      |  21 |
|  93 | 周丙七    |  24 |
|  94 | 孙丁乙    |  32 |
|  95 | 周九一    |  20 |
|  96 | 周九      |  32 |
|  97 | 赵二一    |  26 |
|  98 | 周丁五    |  47 |
|  99 | 孙三      |  38 |
| 100 | 吴十四    |  29 |
+-----+-----------+-----+
100 rows in set (0.00 sec)

mysql> 
九月茅桃 2014-08-28
  • 打赏
  • 举报
回复
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `pro3`$$
CREATE  PROCEDURE `pro3`(num INT)
BEGIN
DECLARE fname CHAR(1);
DECLARE name1 CHAR(1);
DECLARE name2 CHAR(1);
DECLARE fullname VARCHAR(3);
DECLARE pre_fullname VARCHAR(3) DEFAULT '';
DECLARE age INT;
DECLARE i INT DEFAULT 1;
WHILE i <=num DO
	SET fname = SUBSTRING('赵钱孙李周吴郑王',FLOOR(1+8*RAND()),1);  
	SET name1 = SUBSTRING('一二三四五六七八九十甲乙丙丁',ROUND(1+14*RAND()),1); 
	SET name2 = SUBSTRING('一二三四五六七八九十甲乙丙丁',ROUND(1+14*RAND()),1); 

	IF ROUND(RAND())=0 THEN  
	SET fullname = CONCAT(fname,name1);
	END IF;
	IF ROUND(RAND())=1 THEN
	SET fullname = CONCAT(fname,name1,name2);
	END IF;

	SET age = FLOOR(20+31*RAND());  
	-- 给临时变量赋值,看最新的一条记录的name值
	SELECT NAME INTO pre_fullname FROM user1 ORDER BY id DESC LIMIT 1;
	-- 开始判断,如果刚赋值的name跟上一次赋值的name值一样,就跳过,i保持不变,继续取值;否则i+1,继续循环取值
	IF fullname=pre_fullname AND i>1 THEN
		SET i=i;
	ELSEIF fullname IS NULL THEN
		SET i=i;		
	ELSE
		INSERT INTO user1 VALUES(NULL,fullname,age);  
		SET i = i + 1; 
	END IF ;

END WHILE;
END$$
DELIMITER ;


九月茅桃 2014-08-28
  • 打赏
  • 举报
回复
1.很奇怪的是,为什么有这么多连续重复的姓名啊,谁能帮忙解答下这个问题呢? 很简单:因为你的才14个汉字中取一个,有连续2个字重复正常的。 2.是否有更好的办法(必须是mysql+存储过程)去解决这个需求?求教。 可以用java代码或者在应用层用数组写代码实现。 3.我在mysql5.1的手册查询rand()函数看到: -- 若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1))。 若要在7 到 12 的范围(包括7和12)内得到一个随机整数, 可使用以下语句: SELECT FLOOR(7 + (RAND() * 6)); 这种做法不会取到rand()=1导致超出范围? 会应该是 SELECT FLOOR(7 + (RAND() * 5));吧,12-7=5而不是6。

56,677

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧