IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 :

[Msg 2714] Il existe déjà un objet nommé '#tmp' dans la base de données.


Sujet :

Développement SQL Server

  1. #1
    Membre confirmé Avatar de TheBlue
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 167
    Par défaut [Msg 2714] Il existe déjà un objet nommé '#tmp' dans la base de données.
    Bonjour,

    Dans mon code suivant, j'ai besoin de passer dans l'un des deux bloc IF, et stocker le résultat du SELECT dans une table temporaire nommée #tmp

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    DECLARE @cas INT = 1;
     
    IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp
    IF(@cas=1)
    	BEGIN
    		IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp
    		SELECT 'Valeur1' AS Colonne1 INTO #tmp
    	END
    ELSE IF(@cas=2)
    	BEGIN
    		IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp
    		SELECT 'Valeur2' AS Colonne1 INTO #tmp
    	END


    Or rien que l'analyse de la requête (Crtl+F5), ça me ramène l'erreur suivante:

    Msg 2714, Level 16, State 1, Line 13
    Il existe déjà un objet nommé '#tmp' dans la base de données.
    Comment pourrais-je résoudre ce problème ?

    Merci d'avance : )

  2. #2
    Membre confirmé Avatar de TheBlue
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 167
    Par défaut
    Bon j'ai trouvé une solution de contournement, mais j'aimerais bien comprendre pourquoi le code précédent ne fonctionne pas.

    Voilà ce que j'ai trouvé :

    Code SQL : 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
    18
    19
     
    DECLARE @cas INT = 1;
     
    IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp
    CREATE TABLE #tmp ( Colonne1 VARCHAR(20) )
     
    IF(@cas=1)
    	BEGIN
    		INSERT INTO #tmp
    		SELECT 'Valeur1' AS Colonne1
    	END
    ELSE IF(@cas=2)
    	BEGIN
    		INSERT INTO #tmp
    		SELECT 'Valeur2' AS Colonne1
    	END
     
     
    SELECT * from #tmp

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 986
    Billets dans le blog
    6
    Par défaut
    Lorsque vous créez une table temporaire locale, son nom n'est pas le nom que vous lui avez donné mais un nom constitué du nom que vous lui avez donnée suivi d'un certains nombre de blancs soulignés (underscore) et d'un numéro interne de session.

    Voici comment voir cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    USE master;
    GO
    CREATE TABLE #toto (C INT);
    GO
    SELECT * FROM tempdb.INFORMATION_SCHEMA.TABLES;
    Pour supprimer une table temporaire si elle existe, vous devez utiliser la syntaxe suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IF OBJECT_ID('#MaTableTemp') IS NOT NULL
       DROP TABLE #MaTableTemp';
    Et pour vous former :
    Nom : Couverture livre SQL server Eyrolles.jpg
Affichages : 3540
Taille : 105,0 Ko


    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Pour supprimer une table temporaire si elle existe, vous devez utiliser la syntaxe suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IF OBJECT_ID('#MaTableTemp') IS NOT NULL
       DROP TABLE #MaTableTemp';
    Non, la méthode de TheBlue est la bonne, il faut bien vérifier dans tempDB, avec le nom de la table temporaire...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IF OBJECT_ID('tempdb..#MaTableTemp') IS NOT NULL
       DROP TABLE #MaTableTemp';

    Le problème vient ici du fait que lors de l'analyse, les branchements ne sont pas évalués, mais les requêtes, oui.
    Le parseur voit donc ici qu'il y a deux requêtes qui vont créer une table temporaire #tmp (sans prendre en compte le fait qu'en fait, une seule des deux requête sera exécutée), et génère une erreur.

    Le fait de créer la table en amont (et donc une seule fois) résous donc le problème.
    L'alternative serait de mettre d'éxecuter les requetes via un EXEC pour différer l'analyse des requêtes au moment de leur exécution.

  5. #5
    Membre confirmé Avatar de TheBlue
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 167
    Par défaut
    Bonjour Frédéric,

    Merci beaucoup pour votre réponse

    Sinon pour :

    Citation Envoyé par SQLpro Voir le message
    ...
    Pour supprimer une table temporaire si elle existe, vous devez utiliser la syntaxe suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IF OBJECT_ID('#MaTableTemp') IS NOT NULL
       DROP TABLE #MaTableTemp';
    Il manque pas quelque chose ? Je parle du "tempdb.." qui précède le nom de la table temporaire comme j'ai fait dans les codes précédents, par ce que quand j'exécute la requête la table temporaire n'est pas supprimée.

    Cordialement.

  6. #6
    Membre confirmé Avatar de TheBlue
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 167
    Par défaut
    Bonjour aieeeuuuuu,

    Merci pour votre réponse, sinon je ne vois comment utiliser le EXEC pour les requêtes, sachant que j'utilise le squelette du code à l'intérieur d'une PS.

    Je me contente donc par la solution du contournement qui consiste à créer la table temporaire avant le bloc IF et de l'alimenter avec INSERT INTO SELECT.

    Merci encore aieeeuuuuu & SQLpro pour votre réponse.

    Cordialement.

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 986
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par TheBlue Voir le message
    Il manque pas quelque chose ? Je parle du "tempdb.." qui précède le nom de la table temporaire comme j'ai fait dans les codes précédents, par ce que quand j'exécute la requête la table temporaire n'est pas supprimée.

    Cordialement.
    Oui, mea culpa !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IF OBJECT_ID('tempdb..#T') IS NOT NULL
       DROP TABLE #T;
    GO
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  8. #8
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par TheBlue Voir le message
    Merci pour votre réponse, sinon je ne vois comment utiliser le EXEC pour les requêtes, sachant que j'utilise le squelette du code à l'intérieur d'une PS.
    Autant pour moi, ça n'irait pas non plus : la table temporaire serait créée dans un nouveau contexte, et n'existerait plus dans la PS


    Je me contente donc par la solution du contournement qui consiste à créer la table temporaire avant le bloc IF et de l'alimenter avec INSERT INTO SELECT.
    Citation Envoyé par TheBlue Voir le message
    Merci encore aieeeuuuuu & SQLpro pour votre réponse.
    Il existe cependant une autre alternative. il suffit de remplacer le branchement du IF par des clauses WHERE, le tout en une seule requete :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    DECLARE @cas INT =2
     
    IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp
    SELECT 'Valeur1' AS Colonne1 
    INTO #tmp
    WHERE @cas = 1
    UNION ALL
    SELECT 'Valeur2' 
    WHERE @cas = 2
     
     
    SELECT *
    FROM #tmp

  9. #9
    Membre confirmé Avatar de TheBlue
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 167
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Il existe cependant une autre alternative. il suffit de remplacer le branchement du IF par des clauses WHERE...
    Voilà une solution élégante (comme disait un prof )

    Je peux mettre donc le sujet en résolu

    Merci & bonne fin de journée/semaine ^^

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 30/01/2018, 15h48
  2. Réponses: 2
    Dernier message: 14/12/2017, 09h37
  3. Réponses: 1
    Dernier message: 26/08/2010, 10h09
  4. Réponses: 1
    Dernier message: 23/10/2005, 00h55
  5. Réponses: 2
    Dernier message: 20/05/2005, 10h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo