C # SqlCommand.ExecuteNonQuery () и SQL SET NOCOUNT ON - PullRequest
0 голосов
/ 17 сентября 2018

Я искал весь день и не верю, что это дубликат других вопросов, таких как ExecuteNonQuery () и SET NOCOUNT ON .

Я также нашел интересный блог о Нахождении запахов кода с помощью SQL-подсказки: проблема SET NOCOUNT (PE008 и PE009) , в которой есть некоторые интересные детали, но все же не отвечающие на мой вопрос.

У меня есть сервер базы данных, на котором администраторы отметили опцию no count для соединений с сервером (В SSMS щелкните правой кнопкой мыши сервер в обозревателе объектов, перейдите в Свойства, выберите страницу Соединения в разделе «Параметры соединения по умолчанию»). , прокрутите вниз, пока не найдете селектор «без счета»).

Исходя из всего прочитанного мною, все больше и больше администраторов вполне могут поставить галочку в опции no count, чтобы повысить производительность, поскольку полученные строки больше не будут отправляться обратно клиенту.

Поэтому мой вопрос в основном касается SqlCommand.ExecuteNonQuery Method в C #, поскольку он опирается на тот факт, что он:

Выполняет инструкцию Transact-SQL для соединения, а возвращает количество затронутых строк .

Но если применяется SET NOCOUNT ON, то результат всегда будет равен -1. Я читал о том, как люди рекомендуют использовать select @rowcount = @@ROWCOUNT, но это не компенсирует тот факт, что вы теряете функциональность от метода SqlCommand.ExecuteNonQuery до такой степени, что вы могли бы просто начать использовать SqlCommand.ExecuteScalar вместо.

Итак, для лучшей практики, мы должны начать устанавливать SQL Server на no count (или, по крайней мере, ожидать, что именно так они начнут настраивать их в ближайшие пару лет), а затем, если это так, Должны ли мы форсировать SET NOCOUNT OFF или понизить SqlCommand.ExecuteNonQuery в пользу select @rowcount = @@ROWCOUNT?

1 Ответ

0 голосов
/ 17 сентября 2018

Около десяти лет назад я начал использовать SqlCop , который использовался для выделения «Процедуры без SET NOCOUNT ON».Со временем я эволюционировал, поэтому я больше не использую это, но мне понравилась концепция, поэтому у меня есть набор модульных тестов, которые запускают запросы метаданных, чтобы найти такие вещи, как SqlCop, используемый для выделения (и многое другое).

Каждый из моих тестов позволяет мне добавлять исключения в каждое правило, что позволяет мне задокументировать обоснование его исключения в комментарии.

Мой текущий тест для этого (которого у меня нетв руки), вероятно, выделяет хранимые процы, которые содержат SELECT, но не SET NOCOUNT ON.Таким образом, INSERT s, UPDATE s и DELETE s остаются с поведением по умолчанию, что позволяет моему коду использовать результат ExecuteNonQuery.Любые дополнительные случаи могут быть исключены из правила.

Это позволяет мне оставить SQL-сервер с поведением по умолчанию, а SP моего приложения выбирают, когда они будут отличаться от Microsoft по умолчанию.

Обратите внимание, что если кто-тоизменив этот параметр по умолчанию, тогда мой код не будет работать, потому что я не последовал совету в самом конце статьи RedGate «Если вам нужно убедиться, что запрос возвращает сообщение rowcount,Вы должны указать это, а не принимать текущую настройку. ".

Это очень разумный совет, в том смысле, что задним числом это замечательная вещь: вы бы знали, что вам нужно установить его, если вы знализначение по умолчанию может быть изменено.Подобно тому, как вы узнали, что сценариев SP как «ЕСЛИ СУЩЕСТВУЕТ, УДАЛЯЙТЕ и СОЗДАЙТЕ» (так что услужливо , предлагаемый SSMS) - это глупый способ сделать это: лучше просто ЕСЛИ НЕ СУЩЕСТВОВАТЬ СОЗДАТЬ заполнитель, а затемИзмените его на фактическое определение (которое позволяет избежать потери метаданных, например разрешений).

Конечно, я мог бы исправить свои SP и добавить новый или измененный модульный тест, чтобы я всегда установить опцию NOCOUNT так или иначе.Но я хочу сказать, что меня не удивит, если установка этого поведения, отличного от настроек по умолчанию, может также испортить любые сторонние продукты, которые вы устанавливаете на этом сервере.(Возможно, это не имеет значения в вашем сценарии.)

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

...