#c# #sql-server-2008 #ado.net
#c# #sql-server-2008 #ado.net
Вопрос:
Мы полагаемся на SqlDataReader.RecordsAffected
подсчет количества строк, измененных хранимой процедурой.
MSDN указывает его определение как:
Количество измененных, вставленных или удаленных строк; 0, если ни одна строка не была затронута или оператор не удался; и -1 для операторов SELECT … Значение этого свойства является кумулятивным. Например, если две записи вставлены в пакетном режиме, значение RecordsAffected будет равно двум.
Похоже, что ADO.NET неверно интерпретирует любой оператор, использующий OUTPUT
предложение как SELECT
оператор, и возвращает -1 RecordsAffected
вместо фактического количества измененных строк.
Например:
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
параметров в наших хранимых процедурах.
Ответ №1:
Что ж, это, безусловно, помогает обратить пристальное внимание на документацию.
Опять же, из MSDN:
Свойство RecordsAffected не устанавливается до тех пор, пока не будут прочитаны все строки и вы не закроете SqlDataReader .
Это в некотором роде ложь.
RecordsAffected
устанавливается перед закрытием SqlDataReader
, но не все время. Мы запрашивали его перед закрытием объекта, и это всегда работало нормально — пока мы не начали использовать OUTPUT inserted
в нашем T-SQL.
Запрос RecordsAffected
после закрытия SqlDataReader
выдает правильное измененное количество строк с OUTPUT
предложением или без него.