2011-08-24 823 views
45

@RowFrom intdebe declarar la variable escalar

@RowTo int

son tanto Parámetros de entrada global para el procedimiento almacenado, y puesto que soy compilar la consulta SQL dentro del procedimiento almacenado con T-SQL, a continuación, utilizando Exec(@sqlstatement) al final del procedimiento almacenado para mostrar el resultado, me da este error cuando trato de usar el @RowFrom o @RowTo dentro de la variable @sqlstatement que se ejecuta ... funciona bien de lo contrario ... por favor ayuda.

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

Además, he intentado incluir lo siguiente en la variable @sqlstatement:

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

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

+0

no voy a añadir una respuesta, ya que no se aplica a esta pregunta en concreto, sino como el primer resultado en Google para este error Vale la pena señalar que el uso de 'GO' provoca una nueva sucursal en la que declaran las variables no son visibles más allá de la declaración. – IronSean

Respuesta

49

No se puede concatenar un int a una cadena. En lugar de:

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

Es necesario:

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

para ayudar a ilustrar lo que está pasando aquí. Digamos @RowTo = 5.

DECLARE @RowTo INT; 
SET @RowTo = 5; 

DECLARE @sql NVARCHAR(MAX); 
SET @sql = N'SELECT ' + CONVERT(VARCHAR(12), @RowTo) + ' * 5'; 
EXEC sp_executeSQL @sql; 

el fin de construir que en una cadena (incluso si en última instancia, será un número), necesito para 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 el caso de que realmente no es necesario volver a declarar a Rt etc. dentro de la cadena @sql, sólo tiene que decir:

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

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

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

EXEC sp_executesql @sql, 
    N'@RowFrom INT, @RowTo INT', 
    @RowFrom, @RowTo; 
+1

Gracias, pero ¿qué hace el N 'do? – bill

+3

Se asegura de que su variable '@ sql' se interprete correctamente como' NVARCHAR' - un requisito si se usa 'sp_executesql' ... –

+1

Bueno, necesitan ser Int porque se usa así " Where RowNum Between @RowFrom and @RowTo" el parámetro @ RowFrom/@ RowTo es int, así como el Declarado .. – bill

4

Para su información, sé que esto es una entrada antigua, pero dependiendo de la configuración de intercalación de base de datos usted puede conseguir este error en una declaración como esta,

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

si por ejemplo typo que el S en el

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

lo siento por escindir 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 capital S en el mensaje, no estoy seguro de por qué, pero creo que es porque el

Set @sql = 

está a la izquierda del signo igual.

+0

Comentario muy importante (y el problema real en mi caso ...) – Dani

0

La sensibilidad de mayúsculas o 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 "Debes declarar la variable escalar" @MyVariable "en Visual Studio (C#) debido a las diferencias entre mayúsculas y minúsculas.

0

Solo agregué lo que me solucionó, donde el autor de la ortografía es el sospechoso this MSDN blog ...

al dividir cadenas SQL a través de múltiples líneas, comprobar que que están coma que separa la cadena de SQL desde sus parámetros (y no tratando de concatenar ellos!) y no falta ningún espacio al final de cada línea de división . No ciencia de cohetes 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; 
Cuestiones relacionadas