2015-04-16 3 views
1

Я использую MS SQL Server 2008 R2 У меня есть приложение C# - его клиент. я встретил следующую ошибку (и до сих пор не могу воспроизвести следующий код клиента приносит «количество затронутых строк» ​​больше, чем это необходимо:.ExecuteNonQuery() и SET NOCOUNT ON

… 
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 довести количество строк, вставленный в «вставить в [Workflows] ...» оператора..

И только этим оператором INSERT. Пророк содержит еще один INSERT перед этим; но клиенту необходимо, чтобы числоOfAffectedRows заполнялось количеством только строк, вставленных с помощью «insert into [Workflows] ...».

Ошибка в следующем: numberOfAffectedRows получил значение 464. Но из содержимого базы данных я вижу, что это должно было быть 419. И ошибка не воспроизводима - к моменту, когда я увидел ее только один раз на erver Productions; и по-прежнему не может воспроизвести его на моем тестовом сервере. На тестовом сервере правильное значение numberOfAffectedRows.

У меня есть следующая версия: причиной ошибки является «SET NOCOUNT ON» в начале TheStoredProc. Here Я нашел ту же проблему:

... Я слышал несколько побочных эффектов использования «SET NOCOUNT ON» a. Функция SQLCommand.ExecuteNonQuery возвращает неправильное количество строк, если хранимой процедуры имеет SET NOCOUNT ON. ...

Чаще всего (на других форумах) Я встретил жалобу о том, что (-1) был возвращен ExecuteNonQuery в этой ситуации.

Как вы думаете, я прав?

Исправление ошибки должно быть следующим: вставить «SET NOCOUNT OFF» прямо перед «вставкой в ​​[Workflows] ...». На моем тестовом сервере это работает нормально - но исходный код тоже работает на тестовом сервере.

+0

Трудно сказать, если вы задаете вопрос или уже имеете ответ – paqogomez

+0

Оба :-) У меня есть ответ; но не на 100% - в нем - поскольку, как я уже сказал, просто не могу воспроизвести ситуацию на тестовом сервере. Поэтому все, что я могу сделать, прежде чем поставить исправление на Production Server, - это спросить людей: «Я прав, или вы можете предложить другую версию, объясняющую, что произошло? Или, может быть, вы видите дефект в моей версии?» –

+0

Я вижу. Может ли ваша проблема кэшироваться? Если вы изменили sproc, это заставит сервер перекомпилировать, а затем дать вам разные результаты. Возможно, nocount является несущественным, и он просто нуждается в обновлении. – paqogomez

ответ

3

Я думаю, что, SET NOCOUNT ON всегда будет возвращать -1 (могут быть случаи, когда это не так, но ...)

ExecuteNonQuery подсчитывает количество строк, затронутых вставки/обновления , но также и любые строки, модифицированные из-за триггеров. У вас есть триггеры в затронутых таблицах в тестовых или производственных базах данных, которые могут вести себя по-другому?

Есть ли причина, по которой вы не хотите явно возвращать количество строк, которое вас интересует? Например, изменение добавить это после вставки вы заинтересованы в:

select @rowcount = @@ROWCOUNT 

, а затем либо вернуть это значение @rowcount, или передать его обратно в выходной параметр. Похоже, что делать это будет в будущем, если вы добавите триггер позже, что приведет к изменению вашего счета без существенного влияния на функциональность вашей системы.

+0

"(могут быть случаи, когда это не так, но ...)« Не могли бы вы немного рассказать об этом? – Endrju

+1

Триггеры !!! ohh триггеры .... +1 – fcm

Смежные вопросы