sql-server - UPDATE 后的 @@ROWCOUNT 是否可靠地衡量*匹配*行?

标签 sql-server tsql

@@ROWCOUNT 是否可靠地告诉您有多少行匹配 UPDATE 中的 WHERE 子句,如与它实际改变的地方有多少不同?

the documentation for @@ROWCOUNT它说:

Data manipulation language (DML) statements set the @@ROWCOUNT value to the number of rows affected by the query and return that value to the client.

(我的强调。)

但是如果我有

CREATE TABLE [Foo] ([a] INT, [b] INT)
GO
INSERT INTO [Foo] ([a], [b]) VALUES (1, 1),(1, 2),(1, 3),(2, 2)
GO
UPDATE [Foo] SET [b] = 1 WHERE [a] = 1
SELECT @@ROWCOUNT
GO

...我看到 3 (匹配 [a] = 1 的行数),而不是 2 (匹配 [a] = 1 的行数)由 UPDATE 修改 - 三行之一的 b 的值已为 1)。这似乎是“受影响”的一个奇怪的定义(不是错误,只是与我通常使用这个词的方式不一致 - 事实上,它对于我想做的事情来说非常方便)。

(例如,类似的 MySQL ROW_COUNT 函数在这种情况下将返回 2。)

这种行为是否可靠,是否理想地记录在我尚未找到的地方?或者是否存在奇怪的边缘情况...

需要明确的是:我并不是在问3是否是正确答案。我问这是否是一个可靠答案,或者是否存在 SQL Server 会遗漏匹配但不需要更改的行的边缘情况。

更新:有几个人问(或暗示)我担心什么样的“可靠性”问题。事实上它们非常模糊,但是,我不知道,复制?交易?分区?它可以使用索引来避免查找行,因为它知道 b 已经是 1,因此它会跳过这些索引? ...?

更新:我希望有人对 SQL Server 如何工作有更“内部”的看法来回答这个问题,但它看起来像触发器示例(以及我玩过的其他示例) by xacinay已经是我们所能达到的最接近的了。而且它看起来非常坚固;如果它在正常情况下表现得如此,并且尽管进行了分区或其他什么,但它并没有那样表现,正如有人所说,那肯定会成为一个错误。这只是经验性的而非学术性的。

最佳答案

documentation for @@ROWCOUNT告诉你的是事实,因为 3 行会可靠受到影响,而不是 MySQL's ROW_COUNT() .

not 2 (the number of rows modified by the UPDATE — one of the three rows already had the value 1 for b).

对于UPDATE,新值和以前的值是否相同并不重要。它只是执行其指示的操作:查找数据源,根据提供的条件过滤行,并对过滤的行应用“设置”更改。

这就是 SQL Server 毫无保留地工作的方式。 MySQL 的工作方式可能有所不同。行计数过程不是 SQL 标准的一部分。因此,每次从一种 RDBMS 切换到另一种 RDBMS 时,您都必须在跳槽之前先检查一下是否存在此类问题。

查看实际更新行为的一些触发器:

CREATE TRIGGER [dbo].[trgFooForUpd]
ON [dbo].[Foo]
FOR UPDATE 
AS begin declare @id int;
      select @id = [a] from INSERTED;
      select * from INSERTED; end;
GO
CREATE TRIGGER [dbo].[trgFooAfterUpd]
ON [dbo].[Foo]
AFTER UPDATE 
AS print 'update done for ' + cast(coalesce( @@ROWCOUNT, -1) as varchar )+'rows'

关于sql-server - UPDATE 后的 @@ROWCOUNT 是否可靠地衡量*匹配*行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23954516/

相关文章:

sql-server - 在 SSIS 中使用动态 Excel 连接管理器时如何配置输入列

mysql - 投影中属性的顺序是否会影响 SQL 查询的执行速度?

sql - 如何为列的每个唯一值仅选择前行?

sql - 如果指定 SELECT DISTINCT 错误,则 ORDER BY 项必须出现在选择列表中

SQL Server : Where condition based on the parameters

sql - 为什么来自 Red Gate SQL Test 的第一个 tSQLt 样本测试在我的系统上失败了?

sql - 在 SELECT * 中仅使用一次连接列

sql - 在多用户 sql 数据库中保存用户所做的更改

基于日期的 SQL Case 语句

sql - 对于具有较大 Id 的行,是否使用 DBCC CHECKIDENT 安全重置主键