如果我运行此命令:
DECLARE @sql NVARCHAR(10) = NULL;
EXEC sp_executesql @sql;
SELECT @@ROWCOUNT;
我希望得到0,甚至NULL也可以。但是我什么也没有,我得到1。为什么执行NULL查询会影响1行?如果我传递“适当的”(non_NULL)查询,那么它将正常工作。
背景(适用于那些关心的人):这来自一个应该生成一些动态SQL来更新一行而仅更新一行的过程。我需要检查1行是否受到影响,而不是0或2或多于2。它工作正常,直到设法生成NULL SQL语句,并且这被视为成功-糟糕!
实际的解决方法是在运行SQL之前检查SQL是否为非NULL,并以与1以外的结果相同的方式对待NULL语句。但是我仍然很好奇为什么它会以这种方式运行。
答案 0 :(得分:4)
这是因为您要将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;
您也可以尝试将初始值设为非零
/*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
答案 1 :(得分:1)
请注意,我的回答纯粹是根据我对SQL Server Management Studio的经验编写的,并不能准确地解释这种行为。 Martin Smith在下面的comment中解释了为什么这不是真的。
看起来sp_executesql根本不使用null参数运行,也许作为故障保护。
尝试分批单独运行“ SELECT @@ ROWCOUNT”,无论当前没有行数,它都会返回1。默认返回值似乎是1,这就是为什么看到此值的原因。