J'ai le morceau de code suivant juste pour m'assurer que la table temporaire n'existe pas. Si la table existe, je veux la tronquer.
CREATE TABLE #LookupLinks( [SyncID] uniqueidentifier, [Name] nvarchar(50), [SQLTable] nvarchar(50) ) --I create this just to test my try-catch BEGIN TRY CREATE TABLE #LookupLinks( [SyncID] uniqueidentifier, [Name] nvarchar(50), [SQLTable] nvarchar(50) ) END TRY BEGIN CATCH PRINT N'#LookupLinks already existed and was truncated.'; TRUNCATE TABLE #LookupLinks END CATCH
Ce que je veux faire:
Ce qui se produit:
ERREUR: Il y a déjà un object nommé '#LookupLinks' dans la database.
Qu'est-ce que je fais mal ici?
C'est parce que SQL Server parsing et valide le lot entier. Ainsi, lors de l'parsing de la deuxième instruction CREATE TABLE
, elle se déconnecte en disant:
Il y a déjà un object nommé '#LookupLinks' dans la database.
Voir cet exemple:
IF 1 = 1 BEGIN CREATE TABLE #temp(col INT) END ELSE BEGIN CREATE TABLE #temp(col INT) END
Il produit une erreur disant:
Il y a déjà un object nommé '#temp' dans la database.
La solution de contournement consiste à utiliser Dynamic SQL
.
-- CREATE the table for testing IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL DROP TABLE #LookupLinks CREATE TABLE #LookupLinks( [SyncID] uniqueidentifier, [Name] nvarchar(50), [SQLTable] nvarchar(50) ) -- Final query IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL BEGIN TRUNCATE TABLE #LookupLinks PRINT N'#LookupLinks already existed and was truncated.' END ELSE BEGIN DECLARE @sql NVARCHAR(MAX) = '' SELECT @sql = ' CREATE TABLE #LookupLinks( [SyncID] uniqueidentifier, [Name] nvarchar(50), [SQLTable] nvarchar(50) )' EXEC sp_executesql @sql PRINT N'#LookupLinks was created.' END
Si vous n'avez pas la première instruction CREATE TABLE
, votre requête fonctionnera très bien. Ou si vous mettez un GO
avant le BEGIN TRY
.
IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL DROP TABLE #LookupLinks -- DROP FIRST CREATE TABLE #LookupLinks( [SyncID] uniqueidentifier, [Name] nvarchar(50), [SQLTable] nvarchar(50) ) --I create this just to test my try-catch GO BEGIN TRY CREATE TABLE #LookupLinks( [SyncID] uniqueidentifier, [Name] nvarchar(50), [SQLTable] nvarchar(50) ) END TRY BEGIN CATCH PRINT N'#LookupLinks already existed and was truncated.'; TRUNCATE TABLE #LookupLinks END CATCH
Pourtant, c'est parce que SQL Server parsing et valide le lot entier. La déclaration GO
mettra les déclarations dans leurs propres lots, ainsi l'erreur ne se produit pas maintenant.
Même la réponse de CeOnSql fonctionnera bien.
TRY CATCH
est une erreur d'exécution. Ce que vous obtenez est une erreur de compilation. Ajouter une PRINT 1
avant votre déclaration et vous verrez que rien ne se fait exécuter.
print 1 CREATE TABLE #LookupLinks( [SyncID] uniqueidentifier, [Name] nvarchar(50), [SQLTable] nvarchar(50) ); BEGIN TRY CREATE TABLE #LookupLinks( [SyncID] uniqueidentifier, [Name] nvarchar(50), [SQLTable] nvarchar(50) ); END TRY BEGIN CATCH PRINT N'#LookupLinks already existed and was truncated.'; TRUNCATE TABLE #LookupLinks END CATCH
Je pense que ce que vous voulez vraiment accomplir est ceci:
IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL --Table already exists BEGIN TRUNCATE TABLE #LookupLinks PRINT N'#LookupLinks already existed and was truncated.'; END ELSE BEGIN CREATE TABLE #LookupLinks( [SyncID] uniqueidentifier, [Name] nvarchar(50), [SQLTable] nvarchar(50) ) END