Запрос нескольких баз данных одновременно - PullRequest
29 голосов
/ 25 января 2010

У меня есть экземпляры 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 ]

44 голосов
/ 25 января 2010
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"
9 голосов
/ 13 декабря 2012

Решение от 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();
3 голосов
/ 22 августа 2014

Ответ Грубера прекрасно работает, но в нем есть синтаксическая ошибка - в конце строки 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
$$
2 голосов
/ 19 марта 2014

Еще один пример запроса нескольких баз данных с использованием процедуры, курсора, объединения всех и подготовленного оператора. Не требует удаления и удаления разрешений:

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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...