Mysql
 sql >> Datenbank >  >> RDS >> Mysql

So führen Sie dieselbe Abfrage für mehrere Tabellen in der Datenbank aus

Der FROM Teil von SELECT -Anweisung muss tatsächliche Tabellennamen haben, kein CHAR(100) Variable, die den Namen der Tabelle enthält. So funktioniert es einfach nicht.

Es sieht so aus, als ob Sie eine bestimmte Abfrage für viele Tabellen mit ähnlicher Struktur in Ihrer Datenbank ausführen möchten. Sehr oft bedeutet dies, dass das Datenbankschema verbessert werden könnte. Aber wenn Sie mit dem umgehen müssen, was Sie haben, müssen Sie dynamisches SQL . Dieser Link zur MySQL-Dokumentation enthält ein Beispiel, "das zeigt, wie man die Tabelle auswählt, für die zur Laufzeit eine Abfrage durchgeführt werden soll, indem der Name der Tabelle als Benutzervariable gespeichert wird", und genau das ist es, was Sie brauchen.

Innerhalb Ihrer Schleife müssen Sie eine Zeichenfolge mit der SQL-Abfrage erstellen und EXECUTE verwenden .

SET @s = CONCAT('select count(distinct signature) from ', tableName);

PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Soweit ich verstehe, ist das Ergebnis der EXECUTE wird an den Aufrufer der gespeicherten Prozedur gesendet, als wäre es ein normaler SELECT , daher erhält der Aufrufer in diesem Beispiel mehrere Resultsets, wenn Ihre Datenbank mehr als eine Tabelle enthält where table_name like "%FAULT_20150320%" .

Hier ist ein Link zu einer weiteren SO-Frage zu MySQL Dynamic SQL So haben Sie dynamisches SQL in einer gespeicherten MySQL-Prozedur mit einigen Beispielen.

Es sieht so aus, als ob Sie so etwas wollen. Es sollte Zählungen aus mehreren Tabellen in signatureCount zusammenfassen Variable.

CREATE PROCEDURE CountSignatures()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE signatureCount INT;
    DECLARE tableName CHAR(100);
    DECLARE tableList CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_name LIKE "%FAULT_20150320%";
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    SET signatureCount = 0;
    OPEN tableList;
    tableListLoop: LOOP
        SET done = FALSE;
        FETCH tableList INTO tableName;
        IF done THEN
            LEAVE tableListLoop;
        END IF;

        SET @VarCount = 0;
        SET @VarSQL = CONCAT('SET @VarCount = (SELECT COUNT(DISTINCT signature) FROM ', tableName, ')');

        PREPARE stmt FROM @VarSQL;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;

        SET signatureCount = signatureCount + @VarCount;
    END LOOP;
    CLOSE tableList;

    SELECT signatureCount;
END$$

Eine andere Variante, wenn die Anzahl der Tabellen, die Sie verarbeiten müssen, nicht groß ist, besteht darin, dynamisch eine große SQL-Anweisung zu erstellen, die alle Tabellen in Ihrer Schleife enthält, und dann EXECUTE es auf einen Schlag:

SELECT 
(COUNT(DISTINCT signature) FROM Table1) +
(COUNT(DISTINCT signature) FROM Table2) +
...
(COUNT(DISTINCT signature) FROM TableN) AS TotalCount