Я использую MS SQL Server 2008 R2. У меня есть приложение C # - его клиент. Я обнаружил следующую ошибку (и все еще не могу ее воспроизвести. Следующий клиентский код приводит к «количеству затронутых строк» больше, чем следовало бы:
…
DbCommand cmd = db.GetStoredProcCommand("TheStoredProc");
int numberOfAffectedRows = db.ExecuteNonQuery(cmd);
…
Сохраненная процедура TheStoredProc в БД выглядит следующим образом:
PROCEDURE TheStoredProc
as
declare @Var1 int
**SET NOCOUNT ON;**
…
insert into [Workflows]
(
WorkflowInstanceID,
Status
)
select WorkflowInstanceID, 1
from #tmp
DROP TABLE #tmp
Это унаследованный код; Я не являюсь его автором. Но из контекста я вижу - Клиент ожидает, что ExecuteNonQuery принесет количество строк, вставленных оператором «вставить в [рабочие процессы]…».
И только этим оператором INSERT. Процедура содержит еще один INSERT перед этим; но Клиенту необходимо заполнить numberOfAffectedRows счетчиком только строк, вставленных с помощью «вставки в [Workflows]…».
Ошибка заключается в следующем: numberOfAffectedRows получило значение 464. Но из содержимого БД я вижу, что это должно было быть 419. И ошибка не воспроизводима - на данный момент я видел ее только один раз на сервере Productions; и все еще не могу воспроизвести его на моем тестовом сервере. На тестовом сервере числоOfAffectedRows верное.
У меня следующая версия: причина ошибки - «SET NOCOUNT ON» в начале TheStoredProc. Здесь я обнаружил ту же проблему:
… Я слышал о нескольких побочных эффектах использования "SET NOCOUNT ON" a. Функция SQLCommand.ExecuteNonQuery возвращает неправильное количество строк, если для хранимой процедуры установлено значение SET NOCOUNT ON. …
Чаще (на других форумах) я встречал жалобу на то, что в этой ситуации ExecuteNonQuery возвращает (-1).
Как вы думаете - я прав?
Исправление должно быть следующим: вставить «SET NOCOUNT OFF» прямо перед «вставить в [Workflows]…». На моем тестовом сервере это работает нормально, но исходный код работает и на тестовом сервере….