基于MariaDB生成随机记录时字段全为NULL的问题排查
存储过程生成随机数据全为NULL的问题分析与修复
问题根源
你的存储过程存在两个核心问题,导致插入的记录全为NULL:
- 游标耗尽后仍执行插入:当前循环逻辑是先执行
fetch操作,接着直接插入数据,最后才判断是否退出。当游标中的数据被取完时,fetch会触发not found处理器,将done设为true,但此时已经执行了insert语句——此时anrede、vorname、nachname已因fetch失败变为NULL,最终插入空值记录。 - 双游标不同步+无效随机:你给游标加上了
order by rand(),但游标是一次性生成完整结果集,rand()只会执行一次,无法实现每次fetch都随机取数;同时两个独立游标会出现其中一个先耗尽数据的情况,后续fetch持续得到NULL值,导致大量空记录。
修复方案
方案1:放弃游标,直接随机取单条数据(更高效简洁)
不需要用游标,直接在循环中每次随机从源表取一条数据插入,同时可以指定插入数量:
CREATE PROCEDURE `create_data` (IN insert_count INT) BEGIN DECLARE i INT DEFAULT 0; DECLARE v_anrede VARCHAR(50); DECLARE v_vorname VARCHAR(50); DECLARE v_nachname VARCHAR(50); WHILE i < insert_count DO -- 随机获取一条称谓和名字 SELECT anrede, vorname INTO v_anrede, v_vorname FROM vorname ORDER BY RAND() LIMIT 1; -- 随机获取一条姓氏 SELECT nachname INTO v_nachname FROM nachname ORDER BY RAND() LIMIT 1; INSERT INTO lp VALUES (NULL, v_anrede, v_vorname, v_nachname); SET i = i + 1; END WHILE; END
方案2:修复游标逻辑(保留游标场景)
如果一定要使用游标,需要调整循环顺序,确保fetch失败时不执行插入,同时去掉游标中无效的order by rand():
CREATE PROCEDURE `create_data` () BEGIN DECLARE done BOOL DEFAULT FALSE; DECLARE anrede VARCHAR(50); DECLARE vorname VARCHAR(50); DECLARE nachname VARCHAR(50); DECLARE _vorname CURSOR FOR SELECT anrede, vorname FROM vorname; DECLARE _nachname CURSOR FOR SELECT nachname FROM nachname; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN _vorname; OPEN _nachname; create_record: LOOP FETCH _vorname INTO anrede, vorname; FETCH _nachname INTO nachname; -- 若任意游标取数失败,直接退出,不执行插入 IF done THEN LEAVE create_record; END IF; INSERT INTO lp VALUES (NULL, anrede, vorname, nachname); END LOOP; CLOSE _vorname; CLOSE _nachname; END
内容的提问来源于stack exchange,提问作者theking2
相关产品推荐
相关产品推荐

