必须声明标量变量

kfgdxczn  于 2022-09-18  发布在  Java
关注(0)|答案(11)|浏览(282)

@RowFrom int

@RowTo int

都是存储过程的全局输入参数,由于我在存储过程中使用T-SQL编译SQL查询,然后在存储过程的末尾使用Exec(@sqlstatement)来显示结果,所以当我尝试在执行的@sqlstatement变量中使用@RowFrom@RowTo时,会出现以下错误。除此之外,它工作得很好。请帮帮忙。

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

此外,我还尝试在@sqlstatement变量中包含以下内容:

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

但是@RowTo仍然不会将其值传递给@Rt并生成错误。

nwwlzxa7

nwwlzxa71#

不能将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 sys.sp_executesql @sql;

为了将其构建为字符串(即使最终它将是一个数字),我需要对其进行转换。但正如您所看到的,数字在执行时仍被视为数字。答案是25,对吧?

在您的情况下,您可以使用适当的参数化,而不是使用串联,如果您养成了这种习惯,您将在某个时候暴露于SQL注入(请参见thisthis

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

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

hgtggwj02#

如果变量在GO之前声明并在GO之后引用,也可能会收到此错误消息。

请看这个question和这个workaround

1aaf6o9v

1aaf6o9v3#

仅供参考,我知道这是一个旧帖子,但根据数据库排序规则设置,您可能会在如下语句中收到此错误,

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

例如,如果您在

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

抱歉,这里已经发布了答案,但这是报告的错误的实际示例。

另请注意,错误不会在消息中显示大写S,我不确定原因,但我认为这是因为

Set @sql =

在等号的左边。

x4shl7ld

x4shl7ld4#

有时,如果您在使用变量之后编写了一条‘go’语句,如果您在这之后尝试使用它,它会抛出这样的错误。尝试删除“go”语句(如果有)。

ui7jx7zq

ui7jx7zq5#

只是为我添加了修复它的方法,根据this MSDN blog,拼写错误是可疑的……

在将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;
xxhby3vn

xxhby3vn6#

这很可能不是问题本身的答案,但在搜索Sql declare scalar variable时,这个问题作为第一个结果弹出,因此我分享了这个错误的可能解决方案。

在我的例子中,这个错误是由在SQL语句后使用;引起的。只要移除它,错误就会消失。

我猜原因与@IronSean在上面的评论中所说的是一样的:
值得注意的是,使用go(在本例中为;)会导致一个新的分支,其中声明的变量在语句之后不可见。

例如:

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
u3r8eeie

u3r8eeie7#

区分大小写也会导致这个问题。

@MyVariable和@myVariable在SQL Server Man中是相同的变量。演播室,并将工作。但是,由于区分大小写的差异,这些变量将导致在Visual Studio(C#)中“必须声明标量变量”@MyVariable“”。

pkbketx9

pkbketx98#

只是对未来的我的一个回答(也许它也会帮助其他人!)如果您尝试在查询编辑器中运行类似以下内容:

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”

这是因为您正在尝试运行一组代码,其中包括存储过程执行和**其下的查询(!)。只需突出显示您想要运行的文件,或删除/注解掉您不感兴趣的文件。

6qfn3psc

6qfn3psc9#

如果其他人遇到了这个问题,而这里没有解决方案让我的SQL文件正常工作,那么我的错误是:

我一直在通过微软的Server Management Studio的‘生成脚本’命令导出我的数据库内容,然后执行一些操作,同时将生成的数据插入到另一个示例中。

由于生成了导出,因此在SQL文件中有一组“go”语句。

我不知道的是,只要执行GO语句,就不能访问在文件顶部声明的变量。因此我不得不删除我的SQL文件中的GO语句,错误“必须声明标量变量XY”也消失了!

bwleehnv

bwleehnv10#

https://docs.microsoft.com/en-us/sql/t-sql/language-elements/sql-server-utilities-statements-go?view=sql-server-ver16所述,用户定义变量的作用域与批处理相关。

--这将产生错误

GO   
    DECLARE @MyVariable int;
    SET @MyVariable = 1;
    GO --new batch of code
    SELECT @MyVariable--CAST(@MyVariable AS 
    int);
 GO

--这不会产生错误

GO   
   DECLARE @MyVariable int;
   SET @MyVariable = 1;
   SELECT @MyVariable--CAST(@MyVariable AS int);
 GO

当我们尝试在动态SQL中传递变量时,我们会得到相同的错误:

GO
DECLARE @ColumnName VARCHAR(100),
        @SQL NVARCHAR(MAX);
SET @ColumnName = 'FirstName';
EXECUTE ('SELECT [Title],@ColumnName FROM Person.Person');  
GO

--在上面的情况下,找不到@ColumnName,因此我们可以这样做:

EXECUTE ('SELECT [Title],' +@ColumnName+ ' FROM Person.Person');

GO
DECLARE @ColumnName VARCHAR(100),
        @SQL NVARCHAR(MAX);
SET @ColumnName = 'FirstName';
SET @SQL = 'SELECT ' + @ColumnName + ' FROM Person.Person';
EXEC sys.sp_executesql @SQL  
GO
daupos2t

daupos2t11#

在END语句后输入‘GO’并选择所有语句,然后执行

相关问题