是否@@ROWCOUNT可靠地告诉你与a中的WHERE子句匹配了多少行UPDATE,而不是实际改变了多少行?
在它的文档中@@ROWCOUNT说:
数据操作语言(DML)语句将
@@ROWCOUNT值设置为受查询影响的行数,并将该值返回给客户端.
(我的重点.)
但如果我有
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
Run Code Online (Sandbox Code Playgroud)
...我看到3(匹配的行数[a] = 1),不2(通过修改后的行数UPDATE -三排的一个已经有值1的b).这似乎是"受影响"的一个奇怪的定义(没有错,只是与我通常使用这个词的方式不一致 - 事实上它实际上非常方便我想做什么).
(ROW_COUNT例如,类似的MySQL 函数会2在这种情况下返回.)
这种可靠的行为,理想情况下记录在某些我还没有找到的地方吗?还是有奇怪的边缘情况......
要明确:我不是在问是否3是正确的答案.我问这是否是一个可靠的答案,或者是否存在SQL Server将遗漏匹配但不需要更改的行的边缘情况.
更新:有几个人问过(或暗示)我担心的"可靠性"问题.事实上,他们非常模糊,但是,不知道,复制?交易?分区?它可以用来避免寻找行的索引,因为它知道b已经存在1,所以它会跳过那些?...?
更新:我希望有人能够更加"内部"地了解SQL Server如何回答这个问题,但看起来像xacinay的触发器示例(以及我玩过的其他人)就像我们要走的那样近要得到.它似乎相当坚实; 如果它在正常情况下表现如此,并且尽管有分区或whatsit它没有表现出来,正如有人说的那样,肯定会有资格作为一个bug.这只是经验而非学术.
xac*_*nay 12
该文档@@ROWCOUNT告诉你实情,因为3行将受到可靠的影响而不是MySQL的ROW_COUNT().
not 2(由UPDATE修改的行数 - 三行中的一行已经具有b的值1).
因为UPDATE新值和先前值相同并不重要.它只是执行以下操作:查找数据源,根据提供的条件过滤行,并对过滤的行应用"set"更改.
这就是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'
Run Code Online (Sandbox Code Playgroud)
为了扩展xacinay的答案,因为他是正确的.
您有3行已更改,因此@@ROWCOUNT是准确的.SQL Server会更改所有行,在更改之前它不会验证值实际上是不同的,因为这需要在更新命令上花费大量开销.只是想象必须检查VARCHAR(MAX)是否实际更改了值.
说明这一点的最简单方法是将yor UPDATE查询实际更改为以下内容:
UPDATE [Foo] SET [b] = 1
OUTPUT INSERTED.b
WHERE [a] = 1
Run Code Online (Sandbox Code Playgroud)
它将输出3行,INSERTED其中"伪"表保存给定更新/插入命令的新值.在一个实例中,该值实际上已经是b = 1并不重要.
如果您想要这一点,您需要将其包含在您的WHERE条款中:
UPDATE [Foo] SET [b] = 1
WHERE [a] = 1 AND [b] <> 1
SELECT @@ROWCOUNT
Run Code Online (Sandbox Code Playgroud)
或者,作为执行此检查的更一般方法,您可以创建一个触发器,并将表中的值/字段与DELETED表中的值进行比较,INSERTED并将其用作行是否实际"更改"的基础.
所以 - 3是准确的数字,因为您已经更新了3行,因为触摸了3行 [a] = 1
| 归档时间: |
|
| 查看次数: |
46782 次 |
| 最近记录: |