Я пишу много сложных хранимых процедур.Некоторые вещи, которые я бы посоветовал:
Не используйте динамический SQl в хранимом процессе, если вы не выполняете процесс поиска с большим количеством параметров, которые могут или не могут понадобиться (тогда это в настоящее время один излучшие решения).Если вы должны использовать динамический SQl в процедуре, всегда есть входной параметр отладки, и если параметр отладки установлен, то выведите оператор SQL, созданный, а не выполняющий его.Это сэкономит часы отладки!
Если вы выполняете более одного запроса действия в процедуре (вставка / обновление / удаление), используйте блоки Try Cacth и обработку транзакций.Добавьте тестовый параметр к входным параметрам, и когда он установлен в 1, всегда выполняйте откат всей транзакции.Перед откатом в тестовом режиме у меня обычно есть раздел, который возвращает значения в таблицах, на которые я влияю, чтобы убедиться, что то, что я делаю с базой данных, действительно то, что я делал.Или вы можете иметь чеки, как показано ниже.Это так же просто, как вставка следующего кода вокруг ваших закомментированных в настоящий момент селектов (и раскомментирование их), когда у вас есть параметр @test.
If @test =1
Begin
Select * from table1 where field1 = @myfirstparameter
End
Теперь вам не нужно проходить, комментировать и раскомментировать каждый раз, когда вы тестируете.
@ test или @debuig всегда должны иметь значение по умолчанию 0 и помещаться последними в списке.Таким образом, их добавление не нарушит существующие вызовы процедуры.
Рассмотрите возможность создания таблиц регистрации и / или регистрации ошибок для процедур, выполняющих вставки / обновления / удаления.Если вы записываете шаги и / или ошибки в переменных таблицы по мере их продвижения, они все еще доступны после отката, который будет вставлен в таблицу журналов.Знание того, какая часть сложного процесса потерпела неудачу и какая была ошибка, может иметь неоценимое значение в дальнейшем.
По возможности не вкладывайте хранимые процедуры в гнездо.Если вам нужно запустить несколько записей в цикле, замените хранимый процесс на тот, у которого есть параметр с табличным значением, и настройте процесс для запуска на основе набора, а не в виде отдельной записи.Это будет работать, если у табличного параметра есть одна запись или много записей.
Если у вас сложный выбор с большим количеством подзапросов или производных таблиц, рассмотрите возможность использования CTE.Рефакторинг любых коррелированных подзапросов или курсоров для лучшего выполнения кода на основе множеств.Всегда думайте с точки зрения наборов данных, а не одной записи.
Не при каких-либо мыслимых обстоятельствах гнездиться взгляды.Падение производительности намного хуже, чем любое небольшое количество сэкономленного времени разработки.И поверьте мне, вложенные представления не экономят время обслуживания, когда изменение должно быть сделано для представления, самого дальнего в цепочке представлений.
Все хранимые процессы (и другой код базы данных) должны находиться под контролем исходного кода.
Переменные таблиц хороши для небольших наборов данных, но временные таблицы (реальные, начинающиеся с # или ##, а не промежуточные таблицы) могут быть более эффективными для производительности в больших наборах данных.При использовании временных таблиц отбрасывайте их, когда они вам больше не нужны.Старайтесь избегать использования глобальных временных таблиц.
Научитесь писать производительный SQL.Как правило, написать SQL, который будет работать хорошо, так же просто, как и SQL, если вы не знаете техникумы.Если вы пишете сложные хранимые процедуры, нет оправдания тому, что вы не знаете, какие методы работают лучше, чем другие.Узнайте, как убедиться в том, что ваш запрос заслуживает внимания.Избегайте курсоров, коррелированных подзапросов, скалярных функций и других вещей, которые запускаются строка за агонизирующей строкой.