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?
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
.
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:
blat
blat.#pound
créé par un utilisateur dont le schéma par défaut est blat
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
.
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;