2010-01-25 15 views
25

पर कई डेटाबेस क्वेरी करना मेरे पास अपने डेटाबेस में प्रत्येक के साथ वर्डप्रेस इंस्टेंस हैं। एक अद्यतन के लिए मैं मैं सभी सक्रिय प्लगइन सेटिंग्स (विभिन्न डेटाबेस में फैला) और में उन्हें उत्पादन कैसे उपयोग कर सकते हैं सभी सक्रिय प्लगइन, किएक बार

WHERE option_name='active_plugins' 

के माध्यम से एक मेज 'wp_options' में संग्रहीत और सुलभ रहे क्वेरी करने के लिए की जरूरत है एक एकल एसक्यूएल परिणाम? मुझे database.tablename वाक्यविन्यास पता है, लेकिन मैं उपरोक्त Where कथन के साथ वहां से कैसे जा सकता हूं?

एक एकल डाटाबेस में एक अनुरोध इस प्रकार दिखाई देगा:

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

http://www.dottedidesign.com/node/14 –

उत्तर

38
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" 
+0

कूल, धन्यवाद! पहले यूनियन नहीं पता है। – Boldewyn

8

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

यह एक पुन: प्रयोज्य समाधान के लिए एक महान शुरुआत है। लेकिन इसे डिलीमीटर खंडों से लपेटना याद रखें या यह असफल हो जाएगा, esp। MySQL वर्कबेंच में SQL संपादक –

+0

@ जॉय टी: धन्यवाद, मैंने डिलीमीटर खंड जोड़े। एक सामान्य नोट के रूप में, मैं स्कीमा सिंकिंग और पूछताछ से संबंधित समस्याओं के कारण सिंगल-किरायेदार सेटअप से बचने का प्रयास करता हूं। यदि कोई ऐसे सेटअप से फंस गया है, तो मैंने पाया है कि तैयार कथन का उपयोग क्वेरीिंग समस्याओं का समाधान करने का एक शानदार तरीका है। इस तकनीक के साथ, आपको अनिवार्य रूप से ऐसे प्रश्न प्राप्त होते हैं जो बहु-किरायेदार सेटअप का अनुकरण करते हैं। – Gruber

2

फिर भी प्रक्रिया, कर्सर, संघ सभी और तैयार कथन का उपयोग करके कई डेटाबेस पूछने का एक और उदाहरण। ड्रॉप की आवश्यकता होती है और नहीं हटाता है अनुमतियाँ:

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

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

स्टैक ओवरफ़्लो में आपका स्वागत है! एक नया पोस्ट करने के बजाय मौजूदा उत्तर को संपादित करना बेहतर होगा। क्या आपके पास अभी तक संपादन विशेषाधिकार हैं? (मुझे पता है कि वे लोग जो साइट पर नए हैं, कैच -22 में थोड़ी देर के लिए हो सकते हैं ... "ऐसा करने का सही तरीका वास्तव में यह है ... और आपके पास इसके लिए प्रतिनिधि नहीं है। ") यदि आपके पास पर्याप्त प्रतिनिधि है, तो आपको जवाब संपादित करना चाहिए और इसे हटा देना चाहिए। –

+1

इस के जवाब के लिए बहुत बहुत धन्यवाद। हाँ - यह बिल्कुल सही है; मेरे पास कैच -22 था जहां मैं उस पोस्ट पर कोई टिप्पणी जोड़ने में सक्षम नहीं था, या मूल उत्तर को संपादित करने में सक्षम नहीं था --- इसलिए नया जवाब बनाने के अलावा लोगों को इस बारे में चेतावनी देने का कोई तरीका नहीं था। मैंने जो कुछ भी कोशिश की वह अभी हटा दी गई थी --- इसलिए, इसे हटाने के लिए धन्यवाद; और जैसे ही मेरे पास ऐसा करने के लिए पर्याप्त प्रतिष्ठा है, मैं वापस आऊंगा और इसे उचित उत्तर दूंगा! –