Должен ли я хранить необработанные SQL-запросы в моем коде С#, или я должен делегировать их сохраненным функциям в Backgre Postgres?
Если я должен хранить их в коде, так как они могут быть довольно длинными, каков оптимальный способ их хранения (т.е. как константы в отдельном статическом классе)?
Использует ли хранимые функции какое-либо влияние на развертываемость/обновляемость приложения?
Спасибо
Мне очень нравится хранить SQL в текстовых файлах, встроенных в качестве ресурсов в сборку (когда у меня обязательно должно быть значительное число из них, я обычный человек ORM).
Конечно, как вы отформатируете этот текстовый файл, конечно. У вас может быть разграничение с двумя линиями:
UpdateCustomer:
UPDATE CUSTOMER SET NAME=@Name WHERE ID=@ID
FindCustomer:
SELECT NAME, ADDRESS FROM CUSTOMER
WHERE ID=@Id
etc
Нетрудно тогда иметь класс, который загружает это в Dictionary<string,string>
в начальный тип или даже Dictionary<string,SqlStatementHelper>
, где последний является классом, чтобы упростить подготовку оператора с соответствующими значениями. Вы можете использовать любой другой формат, который вы хотите, хотя, в том числе и XML, хотя, если вам не нужно ничего другого, кроме пар имя /sql, это, вероятно, будет чрезмерным.
Недостатком этого является разрыв между SQL и используемым им кодом - вы не можете сразу сказать, какие параметры отсутствуют, не глядя на текстовый файл. С другой стороны (и я просто думаю о манжете здесь) вы, вероятно, могли бы автогенерировать класс из SQL (и немного метаданных) методами с сильно типизированными параметрами.
Смешанное благо хранимых процессов - это то, что они живут в базе данных, а не в вашем коде. Поверхность этого заключается в том, что вы с большей вероятностью сохраните их в синхронизации с изменениями DDL. Недостатком является то, что они больше стараются изменить (IME, во всяком случае), чем запросы, определенные локально. (Есть, очевидно, много других плюсов и минусов, но я ограничиваю себя удобной стороной здесь.)
Что касается обслуживания - хорошо, я полагаю, что у вас будет только обновление "только базы данных" только для таблиц и хранимых процедур, без каких-либо клиентов, которые должны знать вообще - в этом случае сохраненные процессы будут лучше переехать. По моему опыту (конечно же, с пользовательскими решениями, в которых есть только несколько приложений, обращающихся к базе данных, поэтому совместимость не такая уж большая проблема) изменения кода почти повсеместны, но изменения в базе данных меньше - в этот момент хранение запросов с помощью приложение означает, что при обновлении вы с меньшей вероятностью должны будете изменить базу данных. Есть ли смысл в этом? У меня еще не было кофе...
Как правило, мы выполняем все наши взаимодействия с базами данных с помощью хранимых процедур вместо прямых операторов SQL; это обеспечивает большую гибкость при настройке изменений схемы и производительности, не перестраивая или передислоцируя двоичные изображения или файлы конфигурации ко всем целям.
Я думаю, что лучше использовать хранимые процедуры, потому что его использование дает производительность. В случае, если это возможно.
Я имею в виду - запросы и исходный код, локальные переменные и т.д. достаточно "независимы" - для этого не требуется много "подготовки", и вы можете просто отправить некоторые переменные в хранимую процедуру в качестве параметров.
Из обычных требований к развертыванию/обновлению сохранение SQL-запросов в коде ограничит ваши параметры, поскольку исходный код с меньшей вероятностью будет перекомпилирован при развертывании по сравнению с обычными модификациями/исправлениями хранимых процедур SQL.
Конечно, это также зависит от того, насколько большой будет ваше "обновление". Этот момент был бы настроен, если бы произошли значительные изменения в бизнес-логике или требуется переключатель базы данных
В любом случае! Но в каждом случае
SQL на уровне кода как постоянный,
SQL на уровне функций SQL