104 votes

Il faut déclarer la variable scalaire

@RowFrom int

@RowTo int

sont tous deux des paramètres d'entrée globaux pour la procédure stockée, et puisque je compile la requête SQL à l'intérieur de la procédure stockée avec T-SQL, j'utilise ensuite Exec(@sqlstatement) à la fin de la procédure stockée pour afficher le résultat, cela me donne cette erreur lorsque j'essaie d'utiliser le @RowFrom ou @RowTo à l'intérieur de la variable @sqlstatement qui est exécutée.. cela fonctionne bien autrement.. s'il vous plaît aidez.

"Il faut déclarer la variable scalaire "@RowFrom"."

Aussi, j'ai essayé d'inclure ce qui suit dans la variable @sqlstatement:

'DECLARE @Rt int'
'SET @Rt = ' + @RowTo

mais @RowTo ne transmet toujours pas sa valeur à @Rt et génère une erreur.

95voto

Aaron Bertrand Points 116343

Vous ne pouvez pas concaténer un entier à une chaîne. Au lieu de :

SET @sql = N'DECLARE @Rt int; SET @Rt = ' + @RowTo;

Vous avez besoin de :

SET @sql = N'DECLARE @Rt int; SET @Rt = ' + CONVERT(VARCHAR(12), @RowTo);

Pour aider à illustrer ce qui se passe ici. Disons que @RowTo = 5.

DECLARE @RowTo int;
SET @RowTo = 5;

DECLARE @sql nvarchar(max);
SET @sql = N'SELECT ' + CONVERT(varchar(12), @RowTo) + ' * 5';
EXEC sys.sp_executesql @sql;

Pour construire cela dans une chaîne (même si finalement ce sera un nombre), je dois le convertir. Mais comme vous pouvez le voir, le nombre est toujours traité comme un nombre lorsqu'il est exécuté. La réponse est 25, n'est-ce pas ?

Dans les versions modernes, vous pouvez utiliser CONCAT() pour éviter les problèmes liés à la prise en charge de NULL ou des conversions :

SET @sql = CONCAT(N'SELECT ', @RowTo, ' * 5');

Mais dans votre cas, vous devriez utiliser une bonne paramétrisation plutôt que la concaténation. Si vous continuez à utiliser la concaténation, vous vous exposerez à l'injection SQL à un moment donné (voir ceci et ceci) :

SET @sql = @sql + ' WHERE RowNum BETWEEN @RowFrom AND @RowTo;';

EXEC sys.sp_executesql @sql,
  N'@RowFrom int, @RowTo int',
  @RowFrom, @RowTo;

34voto

Pierre C Points 540

Vous pouvez également obtenir ce message d'erreur si une variable est déclarée avant un GO et référencée après.

Voir cette question et ce contournement.

7voto

ViRuSTriNiTy Points 3631

Ce n'est probablement pas une réponse à la question en elle-même, mais cette question apparaît en premier résultat lorsqu'on recherche déclarer une variable scalaire Sql, je voulais donc partager une solution possible à cette erreur.

Dans mon cas, cette erreur était causée par l'utilisation de ; après une instruction SQL. Il suffit de le supprimer et l'erreur disparaîtra.

Je pense que la cause est la même que celle mentionnée par @IronSean dans un commentaire précédent :

Il est à noter que l'utilisation de GO (ou dans ce cas ;) crée une nouvelle branche où les variables déclarées ne sont pas visibles au-delà de l'instruction.

Par exemple :

DECLARE @id int
SET @id = 78

SELECT * FROM MyTable WHERE Id = @var; <-- supprimez ce caractère pour éviter le message d'erreur
SELECT * FROM AnotherTable WHERE MyTableId = @var

6voto

htm11h Points 536

Juste pour information, je sais que c'est un ancien message, mais en fonction des paramètres de COLLATION de la base de données, vous pouvez obtenir cette erreur sur une déclaration comme celle-ci,

SET @sql = @Sql + ' WHERE RowNum BETWEEN @RowFrom AND @RowTo;';

si par exemple vous faites une erreur de frappe sur le S dans le

SET @sql = @***S***ql 

désolé de dériver des réponses déjà publiées ici, mais c'est un cas réel de l'erreur signalée.

Notez également que l'erreur n'affichera pas le S majuscule dans le message, je ne sais pas pourquoi, mais je pense que c'est parce que le

Set @sql =

est à gauche du signe égal.

4voto

Parfois, si vous avez une instruction 'GO' écrite après l'utilisation de la variable, et si vous essayez de l'utiliser après cela, cela génère une telle erreur. Essayez de supprimer l'instruction 'GO' si vous en avez une.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X