【发布时间】:2021-01-10 03:10:07
【问题描述】:
我有一个存储过程,当我想在测试环境中使用它时,我用它来“去识别”客户端信息。我正在用随机值替换实际名称和地址。我在一个名为 dict(用于字典)的数据库中有用于女性姓名、男性姓名、姓氏和地址的数据库表。
其中每一个都有一个名为 f_row_id 的字段,它是从 1 到 x 的序列号,对应表中的每条记录。
我们最近升级到 mySQL 8 并且存储过程停止工作。对于我尝试从另一个表中填充随机值的每个字段,我最终都得到了 NULL。在尝试查找现在可以使用的方法时,我无法让以下查询按预期工作:
SELECT
f_enroll_id,
(SELECT f_name FROM dict.dummy_female_first_name fn WHERE fn.f_row_id = (FLOOR(RAND() * 850) + 1) LIMIT 1)
FROM
t_enroll
我的数据表(我最终希望包含随机名称)称为 t_enroll。在那个 (f_enroll_id) 中有一个 ID 字段,我想获取每个 ID 的列表以及该表中每条记录的随机名字。
随机名字表 (dummy_female_first_name) 中有 850 条记录(在我的存储过程中,这是我在过程开始时计算的会话变量)。
当我第一次尝试运行它时,我收到一个错误,即我的子查询返回了多个值。我不明白为什么会这样做,因为 (FLOOR(RAND() * 850) + 1) 应该返回一个整数。所以我添加了 LIMIT 1。但是当我运行它时,大约一半的返回行的名字为 NULL。
我已验证我的名字表中的所有行都有一个行 ID,行 ID 是唯一的,并且数字中没有任何间隙。
你认为这是什么原因造成的?
提前致谢!
这是我正在更新的表的架构:
CREATE TABLE `t_enroll` (
`f_enroll_id` int(15) NOT NULL AUTO_INCREMENT,
`f_status` int(2) DEFAULT NULL,
`f_date_enrolled` date NOT NULL DEFAULT '0000-00-00',
`f_first_name` varchar(20) DEFAULT NULL,
`f_mi` char(1) DEFAULT NULL,
`f_last_name` varchar(20) NOT NULL DEFAULT '',
`f_maiden_name` varchar(20) DEFAULT NULL,
`f_dob` date NOT NULL DEFAULT '0000-00-00',
`f_date_fee_received` date NOT NULL DEFAULT '0000-00-00',
`f_gender` int(11) NOT NULL DEFAULT '2',
`f_address_1` varchar(40) DEFAULT NULL,
`f_address_2` varchar(20) DEFAULT NULL,
`f_quadrant` char(2) DEFAULT NULL,
`f_city` varchar(25) DEFAULT NULL,
`f_state` char(2) NOT NULL DEFAULT '',
`f_county` varchar(3) NOT NULL,
`f_zip_code` varchar(10) DEFAULT NULL,
PRIMARY KEY (`f_enroll_id`),
KEY `f_date_enrolled` (`f_date_enrolled`),
KEY `f_last_name` (`f_last_name`),
KEY `f_first_name` (`f_first_name`),
KEY `f_dob` (`f_dob`),
KEY `f_gender` (`f_gender`)
ENGINE=InnoDB AUTO_INCREMENT=532 DEFAULT CHARSET=latin1 COMMENT='InnoDB free: 15360 kB';
这是我从中提取名称的字典表的架构:
CREATE TABLE `dummy_female_first_name` (
`f_row_id` int(11) NOT NULL,
`f_name` varchar(25) NOT NULL,
PRIMARY KEY (`f_row_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
正如我在评论中提到的,我找到了一种使用 ORDER BY RAND() LIMIT 1 变体的替代方法。但我仍然很好奇是什么阻止了我原来的方法失败。这在最近的 mySQL 版本中有所改变,因为它曾经可以工作。
再次感谢。
【问题讨论】:
-
请显示您的架构(
show create table dict.dummy_female_first_name和show create table t_enroll的输出)和重现问题的示例数据 -
显然我仍在学习在这里发帖,因为我不确定如何提供我的架构。当我尝试将其添加为评论时,它说我的评论太长了。我应该在多个小 cmets 中发布架构吗?
-
顺便说一句,我找到了解决它的方法。如果我更改: (SELECT f_name FROM dict.dummy_female_first_name fn WHERE fn.f_row_id = (FLOOR(RAND() * 850) + 1) LIMIT 1) 到 (SELECT f_name FROM dict.dummy_female_first_name fn ORDER BY RAND() LIMIT 1) 它工作。
-
不,只需编辑您的问题并添加即可。 cmets对于代码或sql不是很有用