如何仅通过MySQL查询获取含特定表条目的同Schema数据库名
没问题,纯MySQL就能搞定这个需求!我给你两种实用的方案,都不用写外部脚本,直接在MySQL里操作就行:
方法一:用存储过程自动遍历数据库
这个方法适合需要重复执行的场景,创建一次存储过程后,调用就能得到结果。
- 先创建存储过程(注意替换
user表和id='john'的条件为你的实际需求):
DELIMITER // CREATE PROCEDURE FindDatabasesWithTargetRecord() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE db_name VARCHAR(255); -- 定义游标,遍历所有非系统数据库 DECLARE db_cursor CURSOR FOR SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA WHERE schema_name NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys'); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; -- 创建临时表存储结果 CREATE TEMPORARY TABLE IF NOT EXISTS ResultDatabases (db_name VARCHAR(255)); TRUNCATE TABLE ResultDatabases; OPEN db_cursor; read_loop: LOOP FETCH db_cursor INTO db_name; IF done THEN LEAVE read_loop; END IF; -- 动态生成SQL,检查当前数据库的目标表是否存在指定记录 SET @sql = CONCAT( 'INSERT INTO ResultDatabases SELECT ''', db_name, ''' FROM ', db_name, '.user WHERE id = ''john'' LIMIT 1' ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END LOOP; CLOSE db_cursor; -- 输出最终结果 SELECT db_name FROM ResultDatabases; -- 清理临时表 DROP TEMPORARY TABLE ResultDatabases; END // DELIMITER ;
- 调用存储过程获取结果:
CALL FindDatabasesWithTargetRecord();
方法二:动态生成UNION查询一次性执行
如果只是临时查一次,不想创建存储过程,可以用这个方法:
- 先运行下面的SQL,生成查询代码:
SELECT CONCAT( 'SELECT DISTINCT ''', schema_name, ''' AS db_name FROM ', schema_name, '.user WHERE id = ''john'' UNION ALL ' ) FROM INFORMATION_SCHEMA.SCHEMATA WHERE schema_name NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');
- 把输出的所有行拼接起来,去掉最后一个多余的
UNION ALL,然后执行拼接后的完整SQL。比如拼接后会是这样:
SELECT DISTINCT 'db1' AS db_name FROM db1.user WHERE id = 'john' UNION ALL SELECT DISTINCT 'db2' AS db_name FROM db2.user WHERE id = 'john' UNION ALL SELECT DISTINCT 'db3' AS db_name FROM db3.user WHERE id = 'john'
执行这段SQL,就会返回所有包含目标记录的数据库名称列表。
注意事项
- 确保当前用户拥有所有目标数据库的SELECT权限,否则会出现权限不足的报错。
- 可以根据实际情况调整排除的系统数据库列表,如果你的业务库和系统库重名,记得修改过滤条件。
- 方法一中的存储过程可以根据需求修改表名和查询条件,比如要查其他字段或表,直接替换对应的部分就行。
内容的提问来源于stack exchange,提问作者Aamir
相关产品推荐
相关产品推荐

