在一个查询中对多个数据库运行相同的查询(MySQL)

时间:2014-12-17 00:28:34

标签: mysql database

我有多个具有相同结构但名称不相关的数据库,我想对所有这些数据库运行此查询:

SELECT FROM <dbname>.`cms_users` WHERE `email` LIKE '%admin.something%'

我在information_schema中搜索了一下,找到了一个名为SCHEMATA的表,其中包含数据库的名称,这些名称最终是我运行上述查询所需要的,我可以通过自己替换数据库名称来手动完成并创建查询。但是我想使用a mysql loop自动执行此操作,但我不确定如何执行此操作以及如何将数据库名称连接到查询并运行它。

我的伪代码如下:

array dbnames= select `SCHEMA_NAME` from `information_schema`.`SCHEMATA`;

loop start on dbnames
SELECT FROM dbnames[index].`cms_users` WHERE `email` LIKE '%admin.bilsi%';
loop end

有任何帮助将这个或更好的逻辑放入mysql语法吗?感谢。

1 个答案:

答案 0 :(得分:7)

SQL Server和其他RDBMS产品允许您在控制台中编写脚本。您可以使用存储过程中可以使用的任何内容。遗憾的是,MySQL更加有限,并且不允许存储过程和函数之外的流控制结构。这意味着没有循环,没有if语句,没有游标。您可以使用变量,但只能使用以@开头的变量。

此外,如果您进行循环,则会将多个结果集发送回客户端。如果您只是从控制台运行查询,这很好。如果结果是您打算使用的程序,则可能不合适(在任何一种情况下都可能不合适)。

如果您是以一种方式执行此操作,请手动获取数据库列表,然后使用复制和粘贴使用UNION ALL构建查询,如下所示:

SELECT FROM `first_db`.`cms_users` WHERE `email` LIKE '%admin.bilsi%'
UNION ALL
SELECT FROM `second_db`.`cms_users` WHERE `email` LIKE '%admin.bilsi%'
UNION ALL
SELECT FROM `third_db`.`cms_users` WHERE `email` LIKE '%admin.bilsi%';

如果您希望数据库的数量发生变化,并且您不想更新查询,或者从程序发送数据库,则可以使用动态SQL。这意味着在字符串变量中构建查询,然后使用MySQL的预处理语句功能提交它。

在控制台上,你可以使用这样的东西(参见:http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html):

SELECT GROUP_CONCAT(CONCAT("SELECT FROM `", SCHEMA_NAME, "`.`cms_users` WHERE `email` LIKE '%admin.bilsi%'") SEPARATOR ' UNION ALL ')
  INTO @stmt_sql 
  FROM INFORMATION_SCHEMA.SCHEMATA 
 WHERE SCHEMA_NAME NOT IN('mysql', 'test', 'tmp');
PREPARE stmt FROM @stmt_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

这将使用INFORMATION_SCHEMA伪数据库中的信息生成上面显示的查询,即按名称列出的数据库列表(MySQL错误地调用模式)。其余的只是根据链接文档准备和执行预准备语句所需的样板代码。

还有其他方法,但它们更加乏味,不会给你带来太大的收获。