我们依靠SqlDataReader.RecordsAffected
来计算存储过程修改的行数。
MSDN将其定义称为:
更改,插入或删除的行数;如果没有行受影响或语句失败,则为0;和SELECT语句的-1 ...此属性的值是累积的。例如,如果以批处理模式插入两个记录,则RecordsAffected的值将为两个。
似乎ADO.NET误解了使用OUTPUT
clause作为SELECT
语句的任何语句,并为RecordsAffected
返回-1而不是实际的修改行数。
例如:
CREATE TABLE dbo.example (
a INT
, b VARCHAR(10)
, c DATETIME2(3) DEFAULT(SYSUTCDATETIME())
);
INSERT INTO dbo.example (
a
, b
)
OUTPUT inserted.c -- Comment out this line and RecordsAffected goes from -1 to 1.
VALUES (
1
, 'blah'
);
这种ADO.NET是出于设计还是出错?
为了记录,我们计划更改代码以使用@@ROWCOUNT
显式捕获已修改行的计数,并将它们作为OUTPUT
参数返回到存储过程中。
答案 0 :(得分:4)
嗯,密切关注文档肯定会有所帮助。
再次,from MSDN:
在读取所有行并关闭SqlDataReader之前,不会设置RecordsAffected属性。
这有点谎言。
在关闭RecordsAffected
之前设置 SqlDataReader
,但不是所有时间。我们在关闭对象之前查询它并且总是工作正常 - 直到我们在T-SQL中开始使用OUTPUT inserted
。
关闭RecordsAffected
后查询SqlDataReader
会产生正确的修改行数,包含或不包含OUTPUT
子句。