web-dev-qa-db-fra.com

Comment vérifier correctement s'il existe une table temporaire dans SQL Server 2005?

J'ai une requête où j'insère des valeurs d'une table:

SELECT ID, NAME INTO #tmpTable1
FROM TableOriginal

La première exécution est correcte, si j'appuie sur F5 (Exécuter) dans MSSMS (Microsoft Sql Server Management Studio), l'erreur s'est produite:

Msg 2714, niveau 16, état 6, ligne 4
Il existe déjà un objet nommé '# tmpTable1' dans la base de données.

Bien. J'ai décidé de vérifier avant d'insérer des données de TableOriginal à #tmpTable1 en utilisant:

IF OBJECT_ID('tempdb.#tmpTable1') IS NOT NULL  
  DROP TABLE #tmpTable1

Ne fonctionne pas, l'erreur s'affiche à nouveau comme ci-dessus.

J'ai vu dans la base de données tempdb le nom de table temporaire suivant:

dbo.#tmpTable1__________________0000007

Pourquoi? Chaque fois que vous créez une table temporaire (en utilisant la première requête), le nom de la table sera généré automatiquement dans MSSMS?

Comment supprimer la table temporaire existante pour faire une nouvelle table avec de nouvelles valeurs?

27
Snake Eyes

Vous êtes sacrément proche - vous devez utiliser deux points dans votre chèque:

IF OBJECT_ID('tempdb..#tmpTable1') IS NOT NULL  
                    ** 
                    |
                  use two dots here!

Fondamentalement, cela signifie: vérifiez le tempDB et je me fiche du schéma dans lequel se trouve la table

Comme Joe l'a dit à juste titre: ce n'est pas correct à 100%: il n'archive pas tous les schémas - il ne fait qu'archiver le schéma du propriétaire par défaut - normalement dbo. Donc, cela fonctionnerait aussi:

IF OBJECT_ID('tempdb.dbo.#tmpTable1') IS NOT NULL  

S'il vous arrive de créer vos objets dans un schéma autre que celui du propriétaire par défaut, vous devrez alors spécifier explicitement le schéma auquel vous faites référence. Mais les tables temporaires dans tempDB sont en effet en train de créer dans le schéma dbo.

54
marc_s

Ce n'est pas une réponse à la question, je voulais juste publier temporairement une réponse au bit sur la mise de .dbo. contre. .. lors du référencement d'une table #temp.

Je n'ai pas trouvé de moyen de faire en sorte qu'une table #temp soit détenue par autre chose que dbo. Essayez-le:

CREATE SCHEMA blat;
GO

CREATE TABLE blat.#pound(id INT);
GO

SELECT 
   OBJECT_ID('tempdb..#pound'), 
   OBJECT_ID('tempdb.dbo.#pound'), 
   OBJECT_ID('tempdb.blat.#pound');

USE tempdb;
GO

SELECT [object_id], SCHEMA_NAME([schema_id]) 
  FROM sys.objects 
  WHERE name LIKE '#pound%';

Résultats:

-1222354987    -1222354987    -1222354987

-1222354987    dbo

C'était sur SQL Server 2012. J'ai testé cela sur SQL Server 2005 et la seule différence était que les valeurs object_id étaient positives. J'ai aussi essayé avec:

  • un schéma existant réellement dans tempdb appelé blat
  • la table blat.#pound créé par un utilisateur dont le schéma par défaut est blat
  • les deux ci-dessus

Dans les trois cas, les mêmes résultats que ci-dessus ont été obtenus.

Vous ne pouvez pas non plus créer deux tables #temp avec le même nom dans des schémas différents:

CREATE TABLE blat.#flab(id INT);
CREATE TABLE dbo.#flab(id INT);

Résultat:

Msg 2714, niveau 16, état 6
Il existe déjà un objet nommé '#flab' dans la base de données.

Ce n'est pas un problème d'analyse (comme la plupart des problèmes de table #temp); vous pouvez exécuter ces deux instructions séparément et recevoir la même erreur.

Donc, c'est une façon longue de dire que vous n'avez jamais besoin de spécifier le schéma lors de la résolution d'un nom de table #temp, il sera toujours créé sous dbo et la résolution au moins sous OBJECT_ID ignorera le schéma que vous spécifiez (OBJECT_SCHEMA_NAME renvoie également toujours dbo lorsqu'il est exécuté dans le contexte de #tempdb, mais pas dans une autre base de données). Tous les paris sont désactivés si vous essayez d'interroger schema_id dans tempdb.sys.objects.

11
Aaron Bertrand
CREATE TABLE #temptable (col1 int);
GO
INSERT INTO #temptable
VALUES (10);
GO
SELECT * FROM #temptable;
GO
IF OBJECT_ID(N'tempdb..#temptable', N'U') IS NOT NULL 
DROP TABLE #temptable;
GO
--Test the drop.
SELECT * FROM #temptable;
1
Aakash Arora