Хранимые процедуры уже несколько лет не пользуются популярностью. В наши дни предпочтительным подходом для доступа к реляционной базе данных является использование O / R-сопоставителя, такого как NHibernate или Entity Framework.
Хранимые процедуры требуют много больше работы для разработки и поддержки. Для каждой таблицы вы должны написать отдельные хранимые процедуры для создания, извлечения, обновления и удаления строки, а также отдельную хранимую процедуру для каждого отдельного запроса, который вы хотите сделать. Кроме того, вы должны написать классы и / или методы в вашем коде для вызова каждой хранимой процедуры. Сравните это с O / R Mapper: все, что вам нужно написать, это ваши определения классов, таблица базы данных и файл отображения. Фактически, современные ORM используют подход, основанный на соглашениях, который устраняет необходимость в отдельном определении отображения.
Хранимые процедуры способствуют плохим практикам разработки, в частности, они требуют, чтобы вы нарушали DRY (не повторяйте себя), поскольку вы должны напечатать список полей в вашей таблице базы данных полдюжины раз или больше минимум . Это большая проблема, если вам нужно добавить один столбец в таблицу базы данных. Невозможно передать объект в качестве параметра хранимой процедуре, только простые типы (строка, целое число, дата / время и т. Д.), Что делает практически невозможным избежать огромных списков параметров (дюжина или более).
Хранимые процедуры способствуют неправильной практике управления конфигурацией. Это вытекает из аргумента, что администраторы баз данных должны иметь возможность изменять их независимо от самого кода. Это приводит к тому, что версия вашего кода, поступающая в производство, которая никогда не была протестирована на интеграцию, не соответствует ни одной конкретной ревизии в управлении исходным кодом и может фактически даже не соответствовать любой ревизии в управлении исходным кодом совсем. По сути, если у вас нет проверяемой записи о том, какая именно редакция вашего кода находится в производстве, у вас возникнут проблемы.
Хранимые процедуры должны развертываться отдельно от основной части вашего кода. Если у вас нет полностью автоматизированного процесса их обновления, существует значительный риск того, что они могут не синхронизироваться с вашей основной кодовой базой в одной или нескольких средах, что приведет к ошибкам. Это особенно проблематично, если вам нужно использовать инструмент деления пополам для контроля версий, в которых произошла ошибка.
Хранимые процедуры негибки. Если вы хотите запросить ваши данные несколькими различными способами (разные порядки сортировки, отложенная загрузка по сравнению с активной загрузкой, разбиение по страницам и т. Д.), Вам потребуется написать множество отдельных хранимых процедур для всех разных вариантов использования, тогда как ORM предоставляют вам гибкие мощный язык запросов (например, Linq to NHibernate).
Хранимые процедуры требуют повторного изобретения колес. Если вам нужен оптимистичный параллелизм, или шаблон единицы работы, или ленивая загрузка, или карта удостоверений, или обработка родительских / дочерних коллекций, или кэширование, или отображения иерархии классов, или почти любые другие шаблоны проектирования, о которых вы читали в книге Мартина Фаулера Шаблоны архитектуры корпоративных приложений вам необходимо самостоятельно перестроить эту функциональность, в то время как O / R mapper дает вам все это, и даже больше, прямо из коробки. Очень часто вам придётся заново изобретать эти колеса, используя код для копирования и вставки, что опять же является плохой практикой.
Хранимые процедуры сложны для модульного тестирования. С помощью ORM вы можете смоделировать код своей базы данных, чтобы иметь возможность быстро протестировать свою бизнес-логику. С помощью хранимых процедур вы должны перестроить всю тестовую базу данных с нуля.
Хранимые процедуры не дают никакого преимущества в производительности. (Крошечные) выгоды, которые вы получаете, передавая по проводу только имя sproc, а не строку SQL, легко компенсируются тем фактом, что слишком велика вероятность того, что вы вызовете одну и ту же процедуру два или три раза с одним и тем же параметров в том же запросе, в то время как ORM смотрел бы в своей карте идентичности и говорил: «Эй, я уже получил этот, нет необходимости делать еще один обход». Более того, утверждение о том, что хранимые процедуры кэшируются на сервере, в то время как специальный SQL не используется, является мифом, который был опровергнут Франсом Боумой в своем посте в блоге: « Хранимые процедуры плохие, хорошо?» 1042 * "
Хранимые процедуры предлагают мало или вообще не дают никаких преимуществ с точки зрения безопасности и не защищают вас от уязвимостей SQL-инъекций. Показательный пример:
Конечно, вы можете писать хранимые процедуры, в которых нет уязвимостей для SQL-инъекций, но вы также можете написать специальный SQL-код на вашем бизнес-уровне, который не имеет уязвимостей для SQL-инъекций, с помощью параметризованных запросов. Присвоение защиты от внедрения SQL-кода хранимым процедурам вместо того, чтобы не разбивать строки SQL вместе, является красной сельдью и полностью вводит в заблуждение.