Когда лучше писать запросы непосредственно в коде, а когда лучше вынести их в процедуры?
Делаю WCF службу, которая должна тянуть данные из MS SQL и отвечать на запросы клиентов и озадачился:
Когда лучше писать запросы непосредственно в коде, а когда лучше вынести их в процедуры?
Пытался найти какие-то паттерны, которые дают рекомендации, но не нашел...
Я выделил 3 возможных решения и их проблемы:
-Если писать все подряд в коде, то код будет ,на мой взгляд, грязным, так как в нем будет много всего, что не входит в специфику языка.
-Если писать все в процедурах, то в процедурах будет много банальностей(Select * from User).
-Если писать элементарные запросы в коде, а сложные выносить в процедуры, то , наверное, код станет тяжелее сопровождать. Есть и еще 1 проблема: как отделить элементарные запросы от сложных? Конструкция из 4 JOIN считается сложной?
Я , лично, склоняюсь к 3 варианту, но существуют ли какие-то соглашения для определения сложности запросов?
Как вы решаете, что нужно выносить в процедуры, а что нет?Что рекомендуется оставлять в коде?
Сам я планирую использовать паттерн Data Mapper.
ОРМ я использовать не планирую(Если только даппер, для удобства использования запросов), так как он сам-то по себе где-то хорош, но когда дело доходит до соединений, то выглядит это ужасно, да и сам по себе запрос не оптимальны может составиться, на мой взгляд чистый SQL запрос наиболее красивее выглядит .
Если говорить о стандартных не сложных запросов, то Entity уже давно никак не проигрывает по скорости чистому SQL. Это уже все давно протестировалось. Но зато простота и гибкость добавляет существенно.
Проблема в следующем. Предположим сейчас ваш запрос прост и сводится к одному SELECT или UPDATE. Проходит полгода, добавляется пара сущностей и этого становится недостаточно - как результат вы переписываете серверный код. При использовании хранимых процедур такая ситуация исключена - вы переписываете хранимку, а серверный код остается тем же.
В процедуры выносятся только запросы, где необходимо сразу же использовать значения предыдущих итераций этого запроса: спуск по дереву множеств (Ваши 4 JOIN'a), фильтрация, рекурсии, поиск пересечений по критериям (data-mining).
Все остальное - лучше использовать непосредственно в коде.
Я лично сторонник того, что в процедуры запросы надо выносить всегда. Т.е. вообще и абсолютно. И тут всего два аргумента, но они весьма весомы, если подумаете:
1. Юзер не имеет прямого доступа к таблицам. В случае запросов в коде - придется что-то с этим решать, да? Либо давать права каждому, либо придумывать некий общий логин, но тогда не отследить просто, кто и что в базе поменял.
2. Прекомпиляция запросов, работа со статистикой. Если запросы делать не в процедурах - то перед выполнением они будут компилироваться - и так каждый раз. Банальности в процедурах - не беда.
Ну и последнее. Внезапно возникает решение переделать код на другой язык/систему. Если вся серверная логика, как положено, на сервере - переделок будет значительно меньше, чем если лазить по всему коду и переписывать это еще раз в другую систему.