Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Jointure table autre base, Nom base passé en Paramètre


Sujet :

Développement SQL Server

  1. #1
    Membre habitué
    Jointure table autre base, Nom base passé en Paramètre
    Bonjour,

    J'ai plusieurs bases Sql Server 2014 sur le même serveur qui ont strictement la même structure.
    Je souhaite écrire 1 procStoc qui fait 1 jointure sur 2 tables contenues dans 2 bases différentes et dont le nom de la 2ème base est passé en paramètre. Ex.:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ALTER PROCEDURE [dbo].[GetInfos]
    @BaseName varchar(8)
    AS BEGIN
     
    SELECT * 
    FROM    MaTable1 T1
                INNER JOIN @BaseName.dbo.MaTable2 T2 ON T2.xx = T1.yy
    ...

    La requête est ici simplifiée pour faciliter la compréhension. En réalité il y a de nombreuses autres jointures et clauses Where et le select n'est pas avec "*".
    J'ai trouvé des articles montrant comment saisir la requête ds un string puis l’exécuter avec EXEC ou EXECUTE sp_executesql mais je ne suis pas Fan de cette façon qui ne permet aucun contrôle de syntaxe.
    J'ai juste besoin de concaténer le nom de la base avec le nom de la table dynamiquement (@BaseName + ".dbo.MaTable2").
    Avez-vous 1 solution à me proposer ?

    Merci

  2. #2
    Rédacteur

    Vous ne pouvez pas faire autrement que de passer par du SQL dynamique. Tout simplement parce qu'une variable c'est une valeur et un identifiant SQL (nom de base, de table, de colonne...) n'est pas une valeur !

    Cependant vous pouvez préalablement tester que le paramètre possède bien la valeur attendue.

    Exemple :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    CREATE OR ALTER PROCEDURE [dbo].[GetInfos]
       @BaseName sysname
    AS 
    SET NOCOUNT ON;
    IF NOT EXISTS(SELECT *
                  FROM   sys.databases 
                  WHERE  name = @BaseName COLLATE French_BIN)
    BEGIN  
       THROW 66666, 'La base de données n''existe pas', 1;
       RETURN;
    END;
    DECLARE @SQL NVARCHAR(max)=  
    N'SELECT * 
    FROM    MaTable1 T1
                INNER JOIN '+ @BaseName + N'.dbo.MaTable2 T2 ON T2.xx = T1.yy;'
    EXEC (@SQL)
    GO


    A +

    Et pour apprendre SQL Server mon livre :

    Cette signature n'a pas pu être affichée car elle comporte des erreurs.

  3. #3
    Membre habitué
    je me doutais qu'il n'y avait pas d'autre solution mais j'espérais un peu.
    Pas facile d’écrire 1 requête complexe de cette manière...MS si tu nous ecoutes...

    Merci pour ton aide.

  4. #4
    Modérateur

    bonjour

    Quelle est la raison d'une telle conception ?

    en alternative, vous pouvez créer une vue qui fait l'union de la table pour toutes les BDD avec le nom de la BDD en colonne :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CREATE VIEW V_MaTable2
    AS 
    SELECT 'BDD1' AS BDD , *
    FROM BDD1.???.dbo.MaTable2 
    UNION ALL
    SELECT 'BDD2' AS BDD , *
    FROM BDD2.???.dbo.MaTable2 
    ...


    et ensuite faire donc
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT ...
    FROM V_MaTable2
    WHERE BDD = @BaseName


    ça évite le SQL dynamique, mais ce n'est pas pour autant une solution idéale...

  5. #5
    Membre habitué
    Cette solution me convient parfaitement.
    La raison est 1 conception discutable de ces bases mais que je ne peux pas changer.
    Merci !

###raw>template_hook.ano_emploi###