Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment exécuter la même requête sur plusieurs tables de la base de données

Le FROM partie du SELECT l'instruction doit avoir des noms de table réels, pas un CHAR(100) variable qui contient le nom de la table. Cela ne fonctionne tout simplement pas comme ça.

Il semble que vous souhaitiez exécuter une requête particulière sur de nombreuses tables ayant une structure similaire dans votre base de données. Très souvent, cela signifie que le schéma de la base de données pourrait être amélioré. Mais, si vous devez gérer ce que vous avez, vous devrez utiliser SQL dynamique . Ce lien vers la documentation MySQL contient un exemple "qui montre comment choisir la table sur laquelle effectuer une requête au moment de l'exécution, en stockant le nom de la table en tant que variable utilisateur", ce qui est exactement ce dont vous avez besoin.

Dans votre boucle, vous devez créer une chaîne avec la requête SQL et utiliser EXECUTE .

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

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

Autant que je sache, le résultat de la commande EXECUTE est envoyé à l'appelant de la procédure stockée comme s'il s'agissait d'un SELECT normal , donc dans cet exemple, l'appelant recevra plusieurs ensembles de résultats si votre base de données a plus d'une table where table_name like "%FAULT_20150320%" .

Voici un lien vers une autre question SO sur le SQL dynamique MySQL Comment avoir SQL dynamique dans la procédure stockée MySQL avec quelques exemples.

On dirait que vous voulez quelque chose comme ça. Il doit résumer les décomptes de plusieurs tables dans signatureCount variables.

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

Une autre variante, si le nombre de tables que vous devez traiter n'est pas important, consiste à créer dynamiquement une grande instruction SQL qui inclut toutes les tables à l'intérieur de votre boucle, puis EXECUTE d'un seul coup :

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