web-dev-qa-db-fra.com

Doit déclarer une erreur de variable scalaire

Ma syntaxe ne cesse de me donner l'erreur ci-dessous, qui me fait penser comme je le pense (et s'il vous plaît veuillez me corriger si je me trompe), j'ai déclaré et défini cette variable ci-dessus.

Msg 137, niveau 15, état 2, ligne 1
Doit déclarer la variable scalaire "@id".

Voici ma syntaxe, et si j'inclus un print @id instruction la valeur correcte sera sortie, mais j'obtiens toujours l'erreur ci-dessus?!

Create Table #temphold
(
  dateadded datetime
  ,dateupdated datetime
  ,id varchar(100)
)

Declare @id varchar(100), @sql varchar(max)
Set @id = '12345'


set @sql = 'insert into   #temphold(dateadded,dateupdated,id) '
          +'select   getdate(),getdate(),COALESCE(@id,'''') '
PRINT @SQL
EXEC(@SQL)


Drop Table #temphold
1
Michael Mormon

@id dans le cadre de la variable d'exécution @sql ne fait rien. Il n'est pas lié à la variable déclarée et définie, sauf si vous créez la chaîne autour d'elle, c'est-à-dire que vous la concaténez comme suit:

set @sql = 'insert into #temphold(dateadded,dateupdated,id) ' +'select getdate(),getdate(),COALESCE(' + @id + ','''') '

Remarquez le + de chaque côté de la variable @id.

À la fin de la journée, @sql n'est qu'une chaîne jusqu'à ce qu'elle soit exécutée à l'aide de la commande EXEC (). Traitez-le simplement comme tel jusqu'à ce qu'il soit compilé en T-SQL complet.

2
Molenpad

Vous pouvez également passer @id in en tant que paramètre de la requête dynamique au lieu de la mettre en tant que littéral. Pour ce faire, vous devez utiliser le sp_executesql fonction au lieu de EXEC. IMO en passant des paramètres dans l'instruction aide à rendre l'instruction générée un peu plus claire/lisible et vous n'avez pas besoin de convertir ou de convertir certains types de données en un équivalent nvarchar. Le faire de cette façon vous donne également une meilleure chance de SQL Server de générer un plan de requête qu'il pourrait réutiliser.

Voici un article sur Stack Overflow qui fournit des comparaisons et des contrastes. Procédure stockée EXEC vs différence sp_executesql?

Voici technet de Microsoft article sur sp_executesql

Create Table #temphold
(
  dateadded datetime
  ,dateupdated datetime
  ,id varchar(100)
)

Declare @id varchar(100), @sql nvarchar(max)
Set @id = '12345'


set @sql = 'insert into   #temphold(dateadded,dateupdated,id) '
          +'select   getdate(),getdate(),COALESCE(@id,'''') '
PRINT @SQL;
execute sp_executesql @statement = @sql, @parameters = N'@id varchar(100)', @id = @id

Drop Table #temphold
2
Aaron

La variable @sql seulement vit là où elle est définie. Les définitions sont délimitées par une instruction "GO". Voyez si cela fonctionne pour vous ...

Set @id = '12345'
Set @sql = 'insert into   #temphold(dateadded,dateupdated,id) '
          +'select   getdate(),getdate(),COALESCE(@id,'''') '
GO
PRINT @sql;
execute sp_executesql @statement = @sql, @parameters = N'@id varchar(100)', @id = @id

Drop Table #temphold
0
Mark McKelvy