该存储过程用于在 当前数据库 中查找包含指定字符串的所有表和字段。
输出结果:每张表只返回一次记录,列出该表中包含目标字符串的字段列表(逗号分隔)。
适用场景:
- 数据库迁移或审计时,快速定位含敏感信息的字段。
- 找出数据库中某个 URL、邮箱、关键字或特定内容所在的字段。
- 不知道具体表或字段名时,快速全库搜索。
DROP PROCEDURE IF EXISTS find_tables_with_string_safe$$
DELIMITER $$
CREATE PROCEDURE find_tables_with_string_safe(IN search_str VARCHAR(255))
BEGINDECLARE done INT DEFAULT 0;DECLARE t_name VARCHAR(255);DECLARE c_name VARCHAR(255);DECLARE sql_text TEXT;DECLARE cur1 CURSOR FORSELECT table_name, column_nameFROM information_schema.columnsWHERE table_schema = DATABASE()AND data_type IN ('char','varchar','text','tinytext','mediumtext','longtext');DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;DROP TEMPORARY TABLE IF EXISTS tmp_find_results;CREATE TEMPORARY TABLE tmp_find_results (table_name VARCHAR(255),column_name VARCHAR(255));OPEN cur1;read_loop: LOOPFETCH cur1 INTO t_name, c_name;IF done = 1 THENLEAVE read_loop;END IF;SET sql_text = CONCAT('INSERT INTO tmp_find_results(table_name, column_name) ','SELECT ''', t_name, ''', ''', c_name, ''' ','FROM `', t_name, '` WHERE `', c_name, '` LIKE ', QUOTE(CONCAT('%', search_str, '%')), ' LIMIT 1');SET @sql_text = sql_text;PREPARE stmt FROM @sql_text;EXECUTE stmt;DEALLOCATE PREPARE stmt;END LOOP;CLOSE cur1;-- 最后返回结果,每张表只取一次表名,多个列会多行返回SELECT table_name, GROUP_CONCAT(column_name SEPARATOR ',') AS matched_columnsFROM tmp_find_resultsGROUP BY table_nameORDER BY table_name;
END$$
DELIMITER ;