我在MySQL中拥有数十个数据库,并且所有数据库都具有相同结构的表log
。是否有简单的方法(一行或几行SQL)列出所有数据库中所有这些类似表的数据?无需编写所有数据库名称?
提前感谢您的帮助。
答案 0 :(得分:2)
系统表information_schema.TABLES
包含表信息,包括拥有该表的模式(数据库)。通过与UNION ALL
的巧妙连接,您可以使用它来构建组合所有log
表的GROUP_CONCAT()
查询。
但是,您将使用骨架SQL片段,
作为分隔符,而不是默认的UNION ALL SELECT col, col2, col3..
并置分隔符。结果将是一个看起来像的查询:
SELECT col, col2, col3 FROM db1.log
UNION ALL SELECT col, col2, col3 FROM db2.log
UNION ALL SELECT col, col2, col3 FROM db3.log...
查询将产生以下效果:
SELECT CONCAT('SELECT col1, col2, col3 FROM ',
GROUP_CONCAT(CONCAT(TABLE_SCHEMA, '.log') SEPARATOR ' UNION ALL SELECT col1, col2, col3 FROM '))
FROM information_schema.TABLES
WHERE TABLE_NAME = 'log';
外部CONCAT()
确保SELECT cols... FROM
开始查询。 GROUP_CONCAT()
在UNION ALL
组件连接的一行中收集所有数据库,CONCAT(TABLE_SCHEMA, '.log')
使用log
表名限定动态检索的数据库名称。
使用SELECT *
可能很诱人,但如果表格中的列都没有相同的列,我会避免使用它。
这将输出一个完整的SQL字符串,然后您可以在任何客户端中执行该字符串。也可以将其放在CREATE PROCEDURE
的正文中,然后创建字符串,然后在其上调用PREPARE
和EXECUTE
。通常,这采取以下形式:
SET @qry = 'SELECT CONCAT(\'SELECT col1, col2, col3 FROM \', GROUP_CONCAT(....'
PREPARE stmt FROM @qry;
EXECUTE stmt;
请记住,在这种情况下,SQL是一个字符串,它必须完整地单引号,你必须反斜杠转义其中的引号。
最后,关于标识符引用的注释。我在这里的代码假设您的数据库名称永远不需要反引号引用。根据数据库的命名方式,可能需要CONCAT()
像
CONCAT('`', TABLE_SCHEMA, '`')