На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> ExecuteNonQuery() и SET NOCOUNT ON , ExecuteNonQuery() возвращает неправильное количество affected rows
    У меня есть:
    MS SQL Server 2008 R2
    C# приложение – его клиент

    Я встретил следующий (причём невоспроизводимый регулярно) баг. Такой вот код на клиенте приносит “количество затронутых строк” большее чем их должно быть на самом деле:

    ExpandedWrap disabled
      ...
      Microsoft.Practices.EnterpriseLibrary.Data.Database db = DatabaseFactory.CreateDatabase("XYZ");
      ...
      DbCommand cmd = db.GetStoredProcCommand("TheStoredProc");
      int numberOfAffectedRows = db.ExecuteNonQuery(cmd);
      ...


    Сама процедура TheStoredProc в базе выглядит примерно так:

    ExpandedWrap disabled
      PROCEDURE TheStoredProc
      as
       
          declare @Var1 int
          
          SET NOCOUNT ON;
      ...............
      insert into [Workflows]
          (
              WorkflowInstanceID,
              Status
          )
          select WorkflowInstanceID, 1
              from #tmp
              
       
          DROP TABLE #tmp


    Всё это писал не я; но из контекста следует что Клиент ожидает что в результате вызова ExecuteNonQuery ему вернётся в numberOfAffectedRows количество строк вставленных процедурой вот в этом операторе INSERT – “insert into [Workflows] …”.

    Причём – только им. В процедуре чуть выше есть ещё один insert; но по контексту очевидно что Клиенту нужно именно и только количество строк вставленных оператором “insert into [Workflows]…”

    Баг состоит в том что в результате выполнения этой процедуры кодом Клиента в его переменной numberOfAffectedRows оказалось число 464; а судя по содержимому базы, должно было быть только 419. Всё усложняется тем что баг “трудноповторимый” – его заметили раз на Production SQL Server-е; а вот повторить его на своём тестовом мне пока не удалось – возвращается правильное количество строк в numberOfAffectedRows.

    Моя версия такова: виновником бага я считаю оператор “SET NOCOUNT ON” в начале процедуры TheStoredProc. Вот здесь https://social.msdn.microsoft.com/Forums/en...etdataproviders говорится:

    Цитата
    ...
    I have heard few side effects of using "SET NOCOUNT ON"
    a. SQLCommand.ExecuteNonQuery function returning wrong number of rows if the stored procedure has SET NOCOUNT ON.
    ...


    “wrong number of rows” – как раз то что у меня. Правда, на форумах в других подобных случаях я чаще всего встречал такие сообщения: “в случае использования SET NOCOUNT ON в процедуре метод ExecuteNonQuery возвращает -1”. У меня же, как видите, не -1 а “несколько большее число, чем правильное”.

    Других версий у меня пока нет.
    Что вы об этом думаете? Правдоподобна моя версия? Так как баг я пока ни разу не воспроизвёл в тестовой среде, мне лишь остаётся оценивать правдоподобность версий…
    Исправить баг я предполагаю вставив в процедуре “SET NOCOUNT OFF” прямо перед “insert into [Workflows]…”. На тестовом сервере попробовал – всё выходит правильно. Но и (как я сказал) старый вариант на тестовом сервере тоже работает правильно…
      PROCEDURE TheStoredProc
      @RowCount int out
      as

      declare @Var1 int

      SET NOCOUNT ON;
      ...............
      insert into [Workflows]
      (
      WorkflowInstanceID,
      Status
      )
      select WorkflowInstanceID, 1
      from #tmp
      select @RowCount = @@rowcount

      DROP TABLE #tmp
      Сообщение отредактировано: Relaxander -
      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0164 ]   [ 17 queries used ]   [ Generated: 23.04.24, 20:55 GMT ]