MySQL存储过程重复执行问题排查与修复求助
解决MySQL存储过程count_null重复输出统计结果的问题
问题现象
编写的count_null存储过程用于统计表字段空值,最初运行正常,现在执行CALL count_null('TABLENAME')时,各字段的空值统计结果会重复输出多次,Workbench日志显示存储过程多次执行,但统计内容本身是正确的。
问题原因
原存储过程的游标查询仅通过table_name过滤字段,而information_schema.columns是全局系统表,会返回所有数据库中同名表的字段信息。如果存在多个库有同名表,游标会获取到重复的字段记录,导致循环重复执行,输出重复结果。
修正后的存储过程代码
DELIMITER // CREATE PROCEDURE count_null(IN tbl_name VARCHAR(255)) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE col_name VARCHAR(255); DECLARE col_type VARCHAR(50); DECLARE cur CURSOR FOR SELECT column_name, data_type FROM information_schema.columns WHERE table_name = tbl_name AND table_schema = DATABASE(); -- 新增:过滤当前数据库的表 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur; read_loop: LOOP FETCH cur INTO col_name, col_type; IF done THEN LEAVE read_loop; END IF; SET @where_clause = ''; IF col_type = 'date' THEN SET @where_clause = CONCAT(col_name, ' IS NULL'); ELSE SET @where_clause = CONCAT(col_name, ' IS NULL OR ', col_name, ' = ""'); END IF; SET @sql = CONCAT('SELECT ', QUOTE(col_name), ' AS column_name, COUNT(*) AS count FROM ', tbl_name, ' WHERE ', @where_clause, ';'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END LOOP; CLOSE cur; END// DELIMITER ;
关键修改说明
- 在游标查询的
WHERE条件中新增AND table_schema = DATABASE(),确保只查询当前连接数据库下目标表的字段,避免跨库同名表导致的重复字段记录。 - 修正了原代码中
""的转义问题,直接使用""即可在MySQL中表示空字符串。
验证调用
执行原调用语句即可正常输出唯一的统计结果:
CALL count_null('TABLENAME');
内容的提问来源于stack exchange,提问作者Shrm
相关产品推荐
相关产品推荐

