Запрос сразу нескольких баз данных
у меня есть экземпляры WordPress с каждым в своей собственной базе данных. Для обновления мне нужно запросить все активные плагины, которые хранятся в таблице "wp_options" и доступны через
WHERE option_name='active_plugins'
как я могу получить доступ к все активные настройки плагина (распределенные по нескольким базам данных) и выводить их в одном результате SQL? Я знаю database.tablename
синтаксис, но как я могу идти дальше С выше Where
заявление?
запрос в одной базе данных будет выглядеть так это:
SELECT option_value
FROM `database`.`wp_options`
WHERE option_name="active_plugins"
4 ответов
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"
решение 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();
ответ Грубера отлично работает, но он имеет синтаксическую ошибку --- в конце строки 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
$$
еще один пример запроса нескольких баз данных с помощью процедуры, курсора, объединения всех и подготовленного оператора. Не требует удаления и удаления разрешений:
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');