@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
и генерирует ошибку.
Вы не можете объединить 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;
Просто к вашему сведению, я знаю, что это старый пост, но в зависимости от настроек базы данных COLLATION вы можете получить эту ошибку в таком операторе
SET @sql = @Sql + ' WHERE RowNum BETWEEN @RowFrom AND @RowTo;';
если, например, вы опечатываете S в
SET @sql = @***S***ql
извините, что вычеркнул ответы, уже размещенные здесь, но это фактический случай сообщенной ошибки.
Также обратите внимание, что ошибка не будет отображать заглавную букву S в сообщении, я не уверен, почему, но я думаю, что это потому, что
Set @sql =
находится слева от знака равенства.
Просто добавьте, что исправило это для меня, где орфографическая ошибка является подозреваемым согласно этот блог MSDN...
При разделении строк SQL на несколько строк убедитесь, что вы запятая, отделяющая вашу строку SQL от ваших параметров (и не пытающаяся их объединить)!) и не пропуская пробелов в конце каждой разделенной строки. Не ракетостроение, но надеюсь, что я спасу кого-то от головной боли.
Например:
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;
Вы также можете получить это сообщение об ошибке, если переменная объявлена перед GO
и на нее есть ссылка.
Смотрите этот вопрос и этот обходной путь.
Чувствительность к регистру также вызовет эту проблему.
@MyVariable и @myvariable - это одни и те же переменные в SQL Server Man. Студия и будет работать. Однако эти переменные приведут к «должен объявить скалярную переменную« @MyVariable »в Visual Studio (C #) из-за различий в зависимости от случая.
Просто ответ для будущего меня (может быть, это поможет кому-то еще тоже!). Если вы попытаетесь запустить что-то подобное в редакторе запросов:
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 выполнение хранимой процедуры И запрос под ним (!). Просто выделите тот, который вы хотите запустить, или удалите / прокомментируйте тот, который вам не интересен.