Soru Tek seferde birden fazla veritabanını sorgulama


Her veritabanında WordPress örnekleri var. Bir güncelleme için 'wp_options' tablosunda saklanan ve üzerinden erişilebilen tüm etkin eklentileri sorgulamam gerekiyor.

WHERE option_name='active_plugins'

Nasıl ulaşabilirim herşey aktif eklenti ayarları (birden fazla veritabanına yayılmış) ve bunları tek bir SQL sonucunda mı çıktı? Biliyorum database.tablename sözdizimi, ama yukarıdaki ile nasıl devam ederim Where Beyan?

Tek bir veritabanında bir istek şöyle görünecekti:

SELECT option_value
  FROM `database`.`wp_options`
 WHERE option_name="active_plugins"

25
2018-01-25 13:45


Menşei


dottedidesign.com/node/14 - Haim Evgi


Cevaplar:


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"

40
2018-01-25 13:48



Birden fazla veritabanı ve tablonuz varsa, tekrarlı çalışmalardan kaçınmak için onu bir döngüye veya bir işleve yerleştirmek mümkündür. - TheHive


Pentium10'un çözümü gayet iyi ama onun dezavantajı, dahil edilecek her şema için sorguyu genişletmeniz gerektiğidir. Aşağıdaki çözüm, sonuç kümesi oluşturmak için hazırlanmış bir deyim kullanır. herşey MySQL sunucunuzda bulunan şemalar wp_options tablo. Bu senin için daha uygun olmalı.

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();

9
2017-12-13 17:21



Bu yeniden kullanılabilir bir çözüm için harika bir başlangıç. Ama bunu sınırlayıcı maddelerle sarmalamayı unutmayın ya da muhtemelen başarısız olacaktır. MySQL WorkBench SQL Düzenleyicisi'nde - Joey T
@Joey T: Teşekkürler, sınırlayıcı maddeler ekledim. Genel bir not olarak, şema eşitleme ve sorgulama ile ilgili sorunlar nedeniyle tek kiracı kurulumlarından kaçınmaya çalışıyorum. Eğer böyle bir kurulum ile sıkışmışsa, hazırlanmış ifadeleri kullanmanın, sorgulama sorunlarını çözmenin harika bir yolu olduğunu anladım. Bu teknikle, çok kiracı kurulumuna öykünen sorgular alırsınız. - Gruber


Gruber'in cevabı harika çalışıyor, ama bir sözdizimi hatası var --- 10. satırın sonunda sahte bir virgül var. Burada sözdizimi hatası olan bir kod var:

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
$$

3
2017-08-21 20:11



Yığın Taşması'na Hoş Geldiniz! Varolan cevabı yeni bir yazı yazmaktan daha iyi olurdu. Henüz düzenleme ayrıcalıklarınız var mı? (Biliyorum ki, siteye yeni gelen insanlar bir süredir bu şekilde bir yakalama-22 olabilirler ... "Bunu yapmanın doğru yolu aslında budur ... ve bunun için bir temsilciniz yok. ") Yeterli temsilcisi varsa, cevabı düzenlemeli ve bunu silmelisiniz. - Keith Pinson
Buna cevabınız için çok teşekkürler. Evet - tam olarak doğru; Bu yazıya bir yorum ekleyemediğim veya orijinal cevabı düzenleyemediğim 22 numaralı bir yakalamam vardı. Bu yüzden insanları yeni bir yanıt oluşturmaktan başka biriyle uyarmanın hiçbir yolu yoktu. Denediğim her şey silindi --- bu yüzden bunu silmediğiniz için teşekkürler; ve geri geleceğim ve bunu yapmak için yeterli itibara sahip olduğumda bunu uygun bir cevap haline getireceğim! - Tom Kerswill


Prosedür, imleç, tüm sendika ve hazır deyimleri kullanarak birden fazla veritabanını sorgulamanın bir başka örneği. Bırakma ve silme izinleri gerektirmez:

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');

2
2018-03-19 08:32