为什么@@ ROWCOUNT使用sp_executesql为NULL语句返回1?

Ric*_*ell 5 sql t-sql sql-server null

如果我运行此命令:

DECLARE @sql NVARCHAR(10) = NULL;
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT;
Run Code Online (Sandbox Code Playgroud)

我希望得到0,甚至NULL也可以。但是我什么也没有,我得到1。为什么执行NULL查询会影响1行?如果我传递“适当的”(non_NULL)查询,那么它将正常工作。


背景(针对那些关心的人):这来自一个应该生成一些动态SQL以更新一行且仅更新一行的过程。我需要检查1行是否受到影响,而不是0或2或大于2。它工作正常,直到设法以某种方式设法生成NULL SQL语句,并且这被视为成功-糟糕!

实际的解决方法是在运行SQL之前检查SQL是否为非NULL,并以与1以外的结果相同的方式对待NULL语句。但是我仍然很好奇为什么它表现为这种方式。

Sam*_*ami 5

这是因为您已分配NULL给变量。进行简单赋值的语句始终将@@ROWCOUNT值设置为1。

请参见下面的示例。因为Management Studio可以在连接上运行自己的查询并弄乱@@ROWCOUNT值,所以它开始选择空结果集以确保初始@@ROWCOUNT值为零。

如果没有分配,则SELECT @@ROWCOUNT返回0(初始值尚未修改)。否则返回1

/*Ensure @@ROWCOUNT starts off at 0*/
SELECT 1 WHERE 1 = 0;

DECLARE @sql NVARCHAR(10);
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT;

GO

/*Ensure @@ROWCOUNT starts off at 0*/
SELECT 1 WHERE 1 = 0;

DECLARE @sql NVARCHAR(10) = NULL;
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT;
Run Code Online (Sandbox Code Playgroud)

您还可以尝试使用初始值非零的类似方法:

/*Ensure @@ROWCOUNT starts off at 3*/
SELECT 1 UNION SELECT 2 UNION SELECT 3

DECLARE @sql NVARCHAR(10);
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT; --Returns 3

GO

/*Ensure @@ROWCOUNT starts off at 3*/
SELECT 1 UNION SELECT 2 UNION SELECT 3

DECLARE @sql NVARCHAR(10) = NULL;
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT; --Returns 1
Run Code Online (Sandbox Code Playgroud)

  • @Larnu-这是因为SSMS在幕后执行了SELECT @@ SPID;将初始的@@ ROWCOUNT设置为1。然后下面两个都保持不变`DECLARE @sql NVARCHAR(10); EXEC sp_executesql @sql;` (3认同)