Необходимо объявить скалярную переменную

@RowFrom int

@RowTo int

оба являются глобальными входными парамами для хранимой процедуры, и поскольку я компилирую запрос SQL в хранимой процедуре с помощью T-SQL, затем использую Exec(@sqlstatement)в конце хранимой процедуры, чтобы показать результат, это дает мне эту ошибку, когда я пытаюсь использовать @ RowFrom или @ RowTo внутри выполняемой переменной @ sqlstatement.. в противном случае это работает нормально.. пожалуйста помогите.

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

Кроме того, я попытался включить следующее в переменную @ sqlstatement:

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

но @ RowTo все еще не передает свое значение @ Rt и генерирует ошибку.

Комментарии к вопросу (1)
Решение

Вы не можете объединить int с строкой. Вместо:

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

Вам нужно:

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

Чтобы проиллюстрировать, что здесь происходит. Допустим @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;

Чтобы встроить это в строку (даже если в конечном итоге это будет число), мне нужно преобразовать ее. Но, как вы можете видеть, число все еще рассматривается как число при его выполнении. Ответ 25, верно?

В вашем случае вам не нужно повторно объявлять @Rt и т. Д. внутри строки @sql вам просто нужно сказать:

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

Хотя было бы лучше иметь надлежащую параметризацию, например,.

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

EXEC sp_executesql @sql,
  N'@RowFrom INT, @RowTo INT',
  @RowFrom, @RowTo;
Комментарии (4)

Просто к вашему сведению, я знаю, что это старый пост, но в зависимости от настроек базы данных COLLATION вы можете получить эту ошибку в таком операторе

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

если, например, вы опечатываете S в

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

извините, что вычеркнул ответы, уже размещенные здесь, но это фактический случай сообщенной ошибки.

Также обратите внимание, что ошибка не будет отображать заглавную букву S в сообщении, я не уверен, почему, но я думаю, что это потому, что

Set @sql =

находится слева от знака равенства.

Комментарии (1)

Просто добавьте, что исправило это для меня, где орфографическая ошибка является подозреваемым согласно [этот блог MSDN][1]...

При разделении строк SQL на несколько строк убедитесь, что вы запятая, отделяющая вашу строку SQL от ваших параметров (и не пытающаяся их объединить)!) и не пропуская пробелов в конце каждой разделенной строки. Не ракетостроение, но надеюсь, что я спасу кого-то от головной боли.

Например:


db.TableName.SqlQuery(
    "SELECT Id, Timestamp, User " +
    "FROM dbo.TableName " +
    "WHERE Timestamp >= @from " +
    "AND Timestamp 
Комментарии (0)

Вы также можете получить это сообщение об ошибке, если переменная объявлена перед GO и на нее есть ссылка.

Смотрите этот вопрос и этот обходной путь.

Комментарии (0)

Чувствительность к регистру также вызовет эту проблему.

@MyVariable и @myvariable - это одни и те же переменные в SQL Server Man. Студия и будет работать. Однако эти переменные приведут к «должен объявить скалярную переменную« @MyVariable »в Visual Studio (C #) из-за различий в зависимости от случая.

Комментарии (0)

Просто ответ для будущего меня (может быть, это поможет кому-то еще тоже!). Если вы попытаетесь запустить что-то подобное в редакторе запросов:

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'

И вы получаете ошибку:

Должен объявить скалярную переменную "@year"

Это потому, что вы пытаетесь запустить кучу кода, который включает в себя BOTH выполнение хранимой процедуры И запрос под ним (!). Просто выделите тот, который вы хотите запустить, или удалите / прокомментируйте тот, который вам не интересен.

Комментарии (0)