MySQL 一次查询多个数据库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2132654/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Querying multiple databases at once
提问by Boldewyn
I have WordPress instances with each in its own database. For an update I need to query all active plugins, that are stored in a table 'wp_options' and accessible via
我有 WordPress 实例,每个实例都在自己的数据库中。对于更新,我需要查询所有活动插件,这些插件存储在表“wp_options”中并可通过
WHERE option_name='active_plugins'
How can I access allactive plugin settings (spread over multiple databases) and output them in one single SQL result? I know the database.tablename
syntax, but how do I go on from there with the above Where
statement?
如何访问所有活动插件设置(分布在多个数据库中)并在一个 SQL 结果中输出它们?我知道database.tablename
语法,但是我如何从上面的Where
语句开始呢?
A request in a single database would look like this:
单个数据库中的请求如下所示:
SELECT option_value
FROM `database`.`wp_options`
WHERE option_name="active_plugins"
回答by Pentium10
SELECT option_value
FROM `database1`.`wp_options`
WHERE option_name="active_plugins"
UNION
SELECT option_value
FROM `database2`.`wp_options`
WHERE option_name="active_plugins"
回答by Gruber
The solution by Pentium10 is good but its drawback is that you have to extend the query for every schema to be included. The below solution uses a prepared statement to produce a result set for allschemas on your MySQL server which have the wp_options
table. This should be more convenient for you.
Pentium10 的解决方案很好,但它的缺点是您必须为要包含的每个模式扩展查询。以下解决方案使用准备好的语句为MySQL 服务器上具有该表的所有模式生成结果集wp_options
。这对你来说应该更方便。
DROP PROCEDURE IF EXISTS `MultipleSchemaQuery`;
DELIMITER $$
CREATE PROCEDURE `MultipleSchemaQuery`()
BEGIN
declare scName varchar(250);
declare q varchar(2000);
DROP TABLE IF EXISTS ResultSet;
create temporary table ResultSet (
option_value varchar(200)
);
DROP TABLE IF EXISTS MySchemaNames;
create temporary table MySchemaNames (
schemaName varchar(250)
);
insert into MySchemaNames
SELECT distinct
TABLE_SCHEMA as SchemaName
FROM
`information_schema`.`TABLES`
where
TABLE_NAME = 'wp_options';
label1:
LOOP
set scName = (select schemaName from MySchemaNames limit 1);
set @q = concat('select option_value from ', scName, '.wp_options where option_name=\'active_plugins\'');
PREPARE stmt1 FROM @q;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
delete from MySchemaNames where schemaName = scName;
IF ((select count(*) from MySchemaNames) > 0) THEN
ITERATE label1;
END IF;
LEAVE label1;
END LOOP label1;
SELECT * FROM ResultSet;
DROP TABLE IF EXISTS MySchemaNames;
DROP TABLE IF EXISTS ResultSet;
END
$$
DELIMITER ;
CALL MultipleSchemaQuery();
回答by Tom Kerswill
Gruber's answer works great, but it has a syntax error --- there's a spurious comma at the end of line 10. Here is the code, with syntax error fixed:
Gruber 的回答很好,但它有一个语法错误 --- 在第 10 行的末尾有一个虚假的逗号。这是代码,修复了语法错误:
DELIMITER $$
CREATE PROCEDURE `MultipleSchemaQuery`()
BEGIN
declare scName varchar(250);
declare q varchar(2000);
DROP TABLE IF EXISTS ResultSet;
create temporary table ResultSet (
option_value varchar(200)
);
DROP TABLE IF EXISTS MySchemaNames;
create temporary table MySchemaNames (
schemaName varchar(250)
);
insert into MySchemaNames
SELECT distinct
TABLE_SCHEMA as SchemaName
FROM
`information_schema`.`TABLES`
where
TABLE_NAME = 'wp_options';
label1:
LOOP
set scName = (select schemaName from MySchemaNames limit 1);
set @q = concat('select option_value from ', scName, '.wp_options where option_name=\'active_plugins\'');
PREPARE stmt1 FROM @q;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
delete from MySchemaNames where schemaName = scName;
IF ((select count(*) from MySchemaNames) > 0) THEN
ITERATE label1;
END IF;
LEAVE label1;
END LOOP label1;
SELECT * FROM ResultSet;
DROP TABLE IF EXISTS MySchemaNames;
DROP TABLE IF EXISTS ResultSet;
END
$$
回答by bancer
Yet another example of querying multiple databases using procedure, cursor, union all and prepared statement. Does not require drop and delete permissions:
使用过程、游标、联合所有和准备好的语句查询多个数据库的另一个例子。不需要删除和删除权限:
USE `my_db`;
DROP PROCEDURE IF EXISTS `CountAll`;
DELIMITER $$
CREATE PROCEDURE `CountAll`(IN tableName VARCHAR(255))
BEGIN
DECLARE db_name VARCHAR(250);
DECLARE exit_loop BOOLEAN;
DECLARE union_query TEXT DEFAULT '';
DECLARE my_databases CURSOR FOR
SELECT DISTINCT `table_schema`
FROM `information_schema`.`tables`
WHERE
`table_schema` LIKE 'myprefix\_%' AND
`table_name` = tableName;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET exit_loop = TRUE;
OPEN my_databases;
get_database: LOOP
FETCH my_databases INTO db_name;
IF exit_loop THEN
-- remove trailing UNION ALL statement
SET union_query = TRIM(TRAILING ' UNION ALL ' FROM union_query);
LEAVE get_database;
END IF;
SET union_query = concat(union_query, 'SELECT COUNT(*) AS qty FROM ',
db_name, '.', tableName, ' UNION ALL ');
END LOOP get_database;
CLOSE my_databases;
SET @final_query = concat('SELECT SUM(qty) FROM (', union_query,
') AS total;');
PREPARE stmt1 FROM @final_query;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END$$
DELIMITER ;
CALL CountAll('wp_options');