2009-07-10 4 views
1

У меня было горячее обсуждение с коллегой по использованию хранимых процедур (SP) в приложении .NET (в базе данных SQL Server 2005). [У него есть фон Microsoft и я Java, что может быть или не быть релевантным].Сохраненная процедура для всего

Мне нужно вставить данные, записанные в пользовательском интерфейсе. Для этого я бы написал SP и использовал это в коде .NET? Это не требуется, но каковы плюсы и минусы использования SP?

Другой сценарий:

я поддерживаю список городов. Пользователь может добавлять города с помощью пользовательского интерфейса. Как вы ожидаете, пользователь не может войти в дублирующий город. При повторной записи произойдет ошибка. это может быть реализовано несколькими способами:

  1. В моем коде выполните запрос выбора, чтобы проверить, существует ли он, а затем, если не вставить город, в противном случае это ошибка в пользовательском интерфейсе.
  2. Вставьте непосредственно и из-за уникального индекса SQLException будет пойман. Взгляните на SQLException, чтобы проверить, какой уникальный индекс нарушен, и показать соответствующую ошибку.
  3. создать один SP и в том, что справиться с выше логики, то есть проверка дубликатов и бросать ошибку или вставить

Какой это правильный путь? (ссылки на хорошие ресурсы приветствуются).

ответ

7

Во-первых, это хорошая идея использовать СФС, а не заявления АПЧРК SQL, потому что: 1) безопасность - нужно всего лишь предоставить разрешение на исполнение sproc, а не на базовых таблиц 2) ремонтопригодность - может пропатчить SP в SQL Server без необходимости перестраивать/развертывать .NET-код, чтобы настроить запрос 3) выполнение - выполнение плана кэширования/повторного использования при использовании sprocs повышает производительность (может быть выполнено и при использовании параметризованного SQL-прямого в вашем .NET) 4) сетевой трафик (нормально, пренебрежимо малые, но SPs избавляет вас от передачи всей инструкции SQL по сети, особенно если большой запрос)

Исключения стоят дорого, поэтому старайтесь избегать ex когда вы можете предотвратить это. Я бы рекомендовал написать sproc, который выполняет проверку IF EXISTS, прежде чем пытаться вставить INSERT запись и только вставить, если она не существует. Просто верните код возврата или выходной параметр, указывающий, что произошло. например 0 = вставлено ОК, -1 = уже существует

Выполняйте все действия в одном запросе sproc, чтобы сохранить совместные поездки DB (т. Е. Сначала не запрашивать db для проверки, а затем отправить другое заявление в INSERT) , Использование проверки EXISTS является наиболее оптимальным способом проверки.

+1

Ваша точка № 3 не совсем правильная, любая заявка sql, которую вы запускаете, либо написана в .net-коде, либо использует sp, будет кэшироваться и оптимизироваться при следующем запуске, sps ничем не отличаются от raw sql в этой связи. Параметризация дает вам безопасность и уменьшает размер вызываемого вызова. –

+1

Если вы отправляете «SELECT * FROM MyTable WHERE Field =« A »», а затем отправляете «SELECT * FROM MyTable WHERE Field =« B »», то в итоге вы получаете 2 отдельных плана выполнения в кеше, а не 1. Это только если вы отправляете в тот же самый adhoc raw SQL min этот случай, что он будет повторно использовать план выполнения, следовательно, параметризация является ключевой, например SELECT * FROM MyTable WHER Поле = @ Значение, которое будет выполняться так же, как и sproc, как любое значение, которое вы назначаете @Value, приведет к тому, что ТАЙНЫЙ план выполнения будет использоваться. – AdaTheDev

+0

Если вы пишете adhoc Queries, они будут кэшироваться для ТОЧНОГО запроса, как говорит AdaTheDev.Вот почему использование sprocs лучше, потому что вся вещь кэшируется, и значения могут быть легко изменены. – AutomatedTester

2

Если вы намереваетесь написать один sp, который будет выполнять все проверки и вставить, если он в состоянии, то почему бы не вернуть число строк, измененных и если оно больше нуля, ваш метод был успешным. Я бы избегал исключения, идея состоит в том, что неспособность вставить не является исключительной, просто нежелательной. Метод вставки, который хранит хранимую процедуру proc, может считывать выходной параметр и указывать его вызывающему, если он вставил что-либо.

7

Как правило, если приложение является единственным пользователем данной схемы базы данных, я бы посоветовал использовать прямой SQL (т. Е. Нет SP). Если база данных распределена между приложениями, становится намного более важным управлять интерфейсом между приложениями и общими данными, а самый простой способ определить этот интерфейс - контролировать доступ к данным через хранимые процедуры.

Использование SPs добавляет сложности системы, и вы не должны добавлять сложность, если для этого нет веской причины. Это также может серьезно затруднить использование приложения хорошими инструментами ORM.

Но, как и при использовании всех эмпирических правил, всегда есть исключения.

+0

Если вы используете хранимые процедуры и изменения базовой структуры, возможно, вам придется изменить ситуацию на +1 сайте. SPs хороши для пакетной обработки, когда данные не нуждаются в выходе из БД. Кроме того, если ваш db доступен третьей стороне, может быть безопаснее передать им SP и несколько таблиц импорта/экспорта. – akarnokd

+0

Абсолютно, никогда не давайте третьим сторонам прямой доступ к столам. В этом отношении я бы дважды подумал о том, чтобы предоставить им доступ к базе данных и вместо этого предоставить им веб-службу. – skaffman

+0

Я согласен с skaffman, сторонняя сторона должна использовать веб-сервис для взаимодействия с вашими данными. –

5

Мне нравится идея разделения уровня данных и уровня бизнес-логики. Поэтому я не помещаю какую-либо бизнес-логику в базу данных, а в код в моем домене.

Если вы используете какой-то ORM, такой как NHibernate, роль базы данных автоматически станет просто хранилищем и ничего больше. Вы должны быть осторожны, когда начинаете внедрять части бизнес-логики в базе данных и другую часть вашего приложения!

С наилучшими пожеланиями

+0

Я не использую ORM, но мне все еще не нравится идея SPs, которая просто взаимодействует с таблицами. SP для выполнения больших задач в базе данных. –

1

Я не думаю, что есть решение один размер. Если вам нужен общий код между решением Java и .NET, то SP в SQL может быть лучшим выбором.

В прошлом я избегал использования хранимых процедур, поскольку это затрудняет развертывание в контролируемой среде. Конечно, вы можете обновить процедуру здесь или там простым способом, но в большой системе это может быть скорее проклятием, чем благословением.

Это зависит от того, насколько вы будете контролировать свою окружающую среду. например Я предпочитаю уверенность в том, что UAT и производство одинаковы. т.е. если он работает в UAT, он будет работать в производстве.

Если есть только два из вас, то это, вероятно, не имеет значения, вы сможете легко устранить любые несоответствия между средами (если у вас есть несколько сред)

Однако для более сложной системы с больше окружений, нескольких регионов, разработчиков в разных часовых поясах, вам нужно как можно проще развертывать и откатывать новую систему. Для развертывания Java это просто вопрос замены символической ссылки и перезапуска службы.

Также довольно легко иметь сразу две версии программного обеспечения, чтобы вы могли выполнять тесты в последнюю минуту, менять и легко менять свою производственную среду в течение дня, а не ждать времени простоя. Возможно, есть простой способ сделать это в SQL, но я не знаком с ним.

Подводя итог: сначала согласовывайте свои требования для всего сквозного процесса, а затем находите решения для соответствия, слишком часто люди начинают с решений, которым они удобны, сосредоточьтесь на одном аспекте, чтобы оправдать свой выбор. Они часто обнаруживают очень поздно в проекте требование, которое является главной головной болью, которая слишком поздно меняться, но было бы просто, если бы это считалось с самого начала.

+0

Я согласен с вами Pater, но люди думают, что развертывание нескольких экземпляров приложения громоздко, а затем изменение SP в одном экземпляре db. Вместо этого я думал, что изменения в db всегда более рискованны, чем любые другие изменения. Также в большинстве случаев изменения не могут быть спрятаны при изменении только SP. –

+0

Развертывание нескольких экземпляров приложения является более громоздким, чем изменения SP. Если у вас есть ошибка в вашей логике запросов, то изменение в одном месте и наличие относительно небольшого окна простоя всегда будет побеждать, когда нужно удалить всю ферму и перераспределить ее. Если ваше приложение правильно обрабатывает SQLExceptions, ваша ферма все еще может принимать запросы и использовать их позже (при условии, что у вас есть закодированные методы повтора) вместо того, чтобы просто показывать ошибку 404 или 500 – AutomatedTester

Смежные вопросы