У меня общая дискуссия с одним из моих разработчиков о философии структурирования хранимых процедур TSQL.
Давайте сделаем пару предположений (чтобы избежать ответов типа «не помещайте бизнес-логику в SP» и т. Д.):
- Бизнес-логика может быть в ИП
- Нет стандартного скриптового слоя CRUD SP
- Сложные процедуры выполняются в одной области действия в SP
- Разрешен динамический SQL
По сути, мой коллега ударился головой о стену вложенных вставок SQL Server в SQL Server. Вы можете вкладывать их за пределы одного уровня.
т.е. :
PROC C вызывается PROC B,
результаты которого вставлены в
временная таблица #X и операции
выполняется, а затем набор результатов
вернулся
PROC B вызывается PROC A,
результаты (наш оригинальный финальный выбор
из PROC C + Преобразования) из
которые вставляются во временную таблицу #Z и выполняются операции, а затем возвращается набор результатов
Это приводит к тому, что SQL Server выдает ошибку, в которой говорится, что вы не можете вкладывать вставки во временные таблицы.
Я согласен с этой логикой, если исходить из наших четырех исходных предпосылок, тогда было бы просто допустимо включить логику, выполняемую в PROC C, непосредственно в PROC B.
Однако мой коллега, будучи хорошим объектно-ориентированным инкапсулятором, считает, что благодаря инкапсуляции последней вложенной вставки код становится более понятным.
С другой стороны, я чувствую, что инкапсуляция кода в операции CRUD, в которых используются временные таблицы, в корне противоречит декларативному и процедурному подходу к управлению данными, присущему SQL и реляционным базам данных.
В конечном счете, его аргумент заключается в том, что если бы логика была просто в одном SP, то в случае изменения схемы таблицы все SP, обращающиеся к таблице, должны были бы измениться. Тем не менее, я считаю, что это маловероятно, поскольку после того, как наша разработка уложит в свои столы, изменения не будут изменены.
Мой аргумент заключается в том, что инкапсуляция вставок временной таблицы для использования во вложении n-й степени (если возможно - к счастью, это не так) приведет к случаю, когда все SP, которые вызывают эту инкапсулированную процедуру (или мы должны теперь называть это методом?) в любом случае придется повторно проверять в случае изменения централизованной инкапсулированной процедуры, поскольку, если ее выходные данные не совпадают, это может привести к разрыву в вызывающем родительском SP.
Полагаю, мой главный вопрос заключается в следующем: по сути, T-SQL - это декларативный, процедурный или императивный язык. На мой взгляд, это явно смесь -> полагаю, если бы мне пришлось создавать рецепт, я бы сказал:
10% декларативный (поскольку в принципе его декларативный)
70% процедурный (в нашем случае, когда бизнес-процессы в процессах)
20% императив (императивные конструкции существуют - особенно в более новых версиях SQL Server)
p.s. На данный момент он предлагает использовать параметр OUTPUT в вызове SP, а не:
вставить в #temp
exec spInsertUpdateTable
У меня совершенно другая неприязнь к параметрам OUTPUT, но я полагаю, что это может сработать. Любые другие предложения?