【问题标题】:Why does @@ROWCOUNT return 1 for a NULL statement using sp_executesql?为什么@@ROWCOUNT 为使用 sp_executesql 的 NULL 语句返回 1?
【发布时间】:2023-03-17 22:43:01
【问题描述】:

如果我运行这个:

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 是否为非 NULL,并将 NULL 语句视为除 1 之外的结果。但我仍然很好奇它为什么会这样。

【问题讨论】:

  • 进行简单赋值的语句总是将@@ROWCOUNT 值设置为1

标签: sql sql-server tsql null


【解决方案1】:

这是因为您将 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

【讨论】:

  • 忽略我关于它不是DECLARE 的观点,我完全忘记了SELECT @@ROWCOUNT 会重置计数。哦!这可以更容易地显示在这里DB<>fiddle,其中@@ROWCOUNT 的值是2EXEC 之后。干得好,今天快结束了。
  • 不过,有趣的是,在我可以访问的瞬间,您的答案中的代码返回 1,而 DBfiddle 和 SQL Fiddle 等工具返回 0
  • @Larnu - 这是因为 SSMS 在后台执行 SELECT @@SPID;,将初始 @@ROWCOUNT 设置为 1。然后以下两个都保持不变DECLARE @sql NVARCHAR(10);EXEC sp_executesql @sql;
  • 谢谢@MartinSmith。这就是原因。
【解决方案2】:

请注意,我的回答纯粹是根据我对 SQL Server Management Studio 的经验编写的,并没有准确解释这种行为。 Martin Smith 在下面的 comment 中解释了为什么这不是真的。

看起来 sp_executesql 根本不使用 null 参数运行,也许是作为故障保护。

尝试在批处理中单独运行“SELECT @@ROWCOUNT”,您会看到它返回 1,而不管当前没有行数。似乎 1 可能是默认返回值,这就是您看到这个的原因。

【讨论】:

  • 这不是正确的答案。在 powershell 中尝试以下操作,您会得到不同的结果:sqlcmd -S {YourServer} -Q "SELECT @@ROWCOUNT;"。 @MartinSmith 在 @Sami 的回答下的 cmets 中解释了为什么当我对此感到困惑时,@@ROWCOUNT 在 SSMS 中返回 1
猜你喜欢
  • 2019-09-06
  • 2021-03-11
  • 1970-01-01
  • 1970-01-01
  • 2016-05-25
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多