sql >> Database teknologi >  >> RDS >> Mysql

Sådan køres den samme forespørgsel mod flere tabeller i databasen

FROM del af SELECT sætningen skal have faktiske tabelnavne, ikke en CHAR(100) variabel, der indeholder navnet på tabellen. Det virker bare ikke sådan her.

Det ser ud til, at du vil køre en bestemt forespørgsel mod mange tabeller med lignende struktur i din database. Ganske ofte betyder det, at databaseskemaet kunne forbedres. Men hvis du skal håndtere det, du har, bliver du nødt til at bruge dynamisk SQL . Dette link til MySQL-dokumentation har et eksempel "der viser, hvordan man vælger den tabel, som en forespørgsel skal udføres på under kørsel, ved at gemme navnet på tabellen som en brugervariabel", hvilket er præcis, hvad du har brug for.

Inde i din loop skal du bygge en streng med SQL-forespørgslen og bruge EXECUTE .

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

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

Så vidt jeg forstår, er resultatet af EXECUTE sendes til den, der ringer til den lagrede procedure, som om det var en normal SELECT , så i dette eksempel vil den, der ringer, modtage flere resultatsæt, hvis din database har mere end én tabel where table_name like "%FAULT_20150320%" .

Her er et link til et andet SO-spørgsmål om MySQL dynamisk SQL Sådan har du dynamisk SQL i MySQL Stored Procedure med nogle eksempler.

Det ser ud til, at du vil have sådan noget. Den skal opsummere tællinger fra flere tabeller i signatureCount variabel.

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

En anden variant, hvis antallet af tabeller, som du skal behandle ikke er meget, er at bygge dynamisk én stor SQL-sætning, der inkluderer alle tabeller inde i din loop og derefter EXECUTE det på én gang:

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


  1. Hvad er en større version alligevel?

  2. Hvordan ville jeg oprette denne matrixstruktur i en HTML-form?

  3. Entity framework tilføjer en ekstra betingelse om hvor-klausul

  4. Kørsel af en MariaDB Galera Cluster uden Orchestration Tools - DB Container Management:Anden del