Debe declarar la variable escalar

81

@RowFrom int

@RowTo int

son parámetros de entrada globales para el procedimiento almacenado, y dado que estoy compilando la consulta SQL dentro del procedimiento almacenado con T-SQL y luego uso Exec(@sqlstatement)al final del procedimiento almacenado para mostrar el resultado, me da este error cuando intento usar el @RowFromo @RowTodentro de la @sqlstatementvariable que se ejecuta .. funciona bien de lo contrario .. por favor ayuda.

"Must declare the scalar variable "@RowFrom"."

Además, intenté incluir lo siguiente en la @sqlstatementvariable:

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

pero @RowTotodavía no pasa su valor @Rt y genera un error.

cuenta
fuente
5
No agregaré una respuesta porque no se aplica específicamente a esta pregunta, pero como primer resultado en Google para este error, vale la pena señalar que el uso GOprovoca una nueva rama donde las variables declaradas no son visibles más allá de la declaración.
IronSean

Respuestas:

75

No puedes concatenar un int a una cadena. En vez de:

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

Necesitas:

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

Para ayudar a ilustrar lo que está sucediendo aquí. Digamos @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;

Para construir eso en una cadena (incluso si finalmente será un número), necesito convertirlo. Pero como puede ver, el número todavía se trata como un número cuando se ejecuta. La respuesta es 25, ¿verdad?

En su caso, realmente no necesita volver a declarar @Rt, etc.dentro de la cadena @sql, solo necesita decir:

SET @sql = @sql + ' WHERE RowNum BETWEEN ' 
    + CONVERT(varchar(12), @RowFrom) + ' AND ' 
    + CONVERT(varchar(12), @RowTo);

Aunque sería mejor tener una parametrización adecuada, p. Ej.

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

EXEC sys.sp_executesql @sql,
  N'@RowFrom int, @RowTo int',
  @RowFrom, @RowTo;
Aaron Bertrand
fuente
2
Gracias, pero ¿qué hacen los N '?
factura el
3
Se asegura de que su @sqlvariable se interprete correctamente como NVARCHAR: un requisito si usa sp_executesql...
Aaron Bertrand
1
Bueno, necesitan ser Int porque se usa así "Donde RowNum Between @RowFrom y @RowTo" El parámetro @ RowFrom / @ RowTo es int, así como Declared ..
proyecto de ley
4
Si, entendido. Está creando una cadena SQL y se encuentra en dos niveles de alcance. En el nivel superior, está construyendo una cadena: toda esa concatenación debe ser con valores de cadena, independientemente de si son '5', 'foo' o 'zuluxxy'. Agregaré un ejemplo para ilustrar.
Aaron Bertrand
9

También puede obtener este mensaje de error si una variable se declara antes de una GOy se hace referencia a ella después.

Vea esta pregunta y esta solución .

Pierre C
fuente
6

Solo para su información, sé que esta es una publicación antigua, pero dependiendo de la configuración de COLLACIÓN de la base de datos, puede obtener este error en una declaración como esta,

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

si, por ejemplo, escribe la S en el

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

Lamento derivar las respuestas ya publicadas aquí, pero esta es una instancia real del error informado.

Tenga en cuenta también que el error no mostrará la S mayúscula en el mensaje, no estoy seguro de por qué, pero creo que es porque el

Set @sql =

está a la izquierda del signo igual.

htm11h
fuente
3

Solo agregué lo que lo solucionó para mí, donde el error ortográfico es el sospechoso según este blog de MSDN ...

Al dividir cadenas SQL en varias líneas, compruebe que está separando por comas su cadena SQL de sus parámetros (¡y no tratando de concatenarlos!) Y que no falte ningún espacio al final de cada línea dividida. No es ciencia espacial, pero espero ahorrarle a alguien un dolor de cabeza.

Por ejemplo:

db.TableName.SqlQuery(
    "SELECT Id, Timestamp, User " +
    "FROM dbo.TableName " +
    "WHERE Timestamp >= @from " +
    "AND Timestamp <= @till;" + [USE COMMA NOT CONCATENATE!]
    new SqlParameter("from", from),
    new SqlParameter("till", till)),
    .ToListAsync()
    .Result;
Tim Tyler
fuente
0

La sensibilidad a mayúsculas y minúsculas también provocará este problema.

@MyVariable y @myvariable son las mismas variables en SQL Server Man. Studio y funcionará. Sin embargo, estas variables darán como resultado un "Debe declarar la variable escalar" @MyVariable "en Visual Studio (C #) debido a diferencias entre mayúsculas y minúsculas.

Hans M Ohio
fuente
0

Solo una respuesta para mi futuro (¡quizás también ayude a alguien más!). Si intenta ejecutar algo como esto en el editor de consultas:

USE [Dbo]
GO

DECLARE @RC int

EXECUTE @RC = [dbo].[SomeStoredProcedure] 
   2018
  ,0
  ,'arg3'
GO

SELECT month, SUM(weight) AS weight, SUM(amount) AS amount 
FROM SomeTable AS e 
WHERE year = @year AND type = 'M'

Y obtienes el error:

Debe declarar la variable escalar "@year"

Esto se debe a que se trata de abrir un montón de código que incluye AMBOS la ejecución del procedimiento almacenado y la consulta por debajo de ella (!). Simplemente resalte el que desea ejecutar o elimine / comente el que no le interesa.

saiyancoder
fuente
0

Si alguien más se encuentra con esta pregunta mientras ninguna solución aquí hizo que mi archivo sql funcionara, aquí está mi error:

He estado exportando el contenido de mi base de datos a través del comando 'Generate Script' de Microsofts 'Server Management Studio y luego realicé algunas operaciones mientras insertaba los datos generados en otra instancia.

Debido a la exportación generada, ha habido un montón de declaraciones "GO" en el archivo sql.

Lo que no sabía era que las variables declaradas en la parte superior de un archivo no son accesibles hasta donde se ejecuta una declaración GO. Por lo tanto, tuve que eliminar las declaraciones GO en mi archivo sql y desapareció el error "Debe declarar la variable escalar xy".

pbur
fuente
0

Lo más probable es que esto no sea una respuesta al problema en sí, pero esta pregunta aparece como primer resultado al buscar, por lo Sql declare scalar variabletanto, comparto una posible solución a este error.

En mi caso, este error fue causado por el uso de ;después de una declaración SQL. Simplemente elimínelo y el error desaparecerá.

Supongo que la causa es la misma que @IronSean ya publicó en un comentario anterior:

Vale la pena señalar que el uso de GO (o en este caso;) provoca una nueva rama donde las variables declaradas no son visibles más allá de la declaración.

Por ejemplo:

DECLARE @id int
SET @id = 78

SELECT * FROM MyTable WHERE Id = @var; <-- remove this character to avoid the error message
SELECT * FROM AnotherTable WHERE MyTableId = @var
ViRuSTriNiDAD
fuente