2013-04-09 2 views
0

У меня есть задача построить запрос (только предложение where) и сохранить его в базе данных. Затем он будет исполнен хранимой процедурой.Лучший подход к динамическому SQL?

Я хочу использовать параметризованный динамический запрос, но неудобно хранить запрос отдельно от параметров в БД, читать как в SQL, так и в параметрах привязки к предложению where. Неловкость заключается в том, что число и тип параметров произвольны.

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

Есть ли элегантный подход к нему?

Я использую .NET и SQL Server.


Пример того, что я говорю:

-- @filterId is passed to the SP 

declare @sql nvarchar(max) 
set @sql = 'select id, name, otherField from Items where' + whereClause 
      from Filters 
      where id = @filterId 

create table #items { 
    id int not null, 
    name nvarchar(100), 
    otherField nvarchar(200) 
} 

insert into #items exec(@sql) 

-- do something with items and return result 

Edit: я советовал, чтобы избежать субъективных условий для того, чтобы получить содержательный ответ. Я считаю, что определение того, что такое «Лучший» и «Элегантный», будет иметь место. Итак, когда я говорю «Лучшее», я ищу решение, которое безопасно, быстро, удобочитаемо и поддерживает больше других решений. «Элегантный» - выполняет именно эту задачу, с минимальным кодом и без слишком большого количества предположений, например. если мне нужно обрабатывать произвольный набор параметров, я не хочу создавать 20 заполнителей для возможных параметров или создавать таблицу со столбцом для всех возможных типов параметров и получать правильное значение с объединением.

+4

Вы когда-нибудь читали «Проклятие и благословения динамического SQL» Эрланда Сомбаргогса (http://www.sommarskog.se/dynamic_sql.html)? – Oded

+1

Здесь, похоже, много помощи [здесь] (https://www.google.com/#q=sql+server+dynamic+stored+procedure). –

+0

Мне нравится, когда модераторы делают комментирование. – Kermit

ответ

0

Я бы сказал, что одна вещь, которую вы делаете неправильно это

exec(@sql) 

Там нет ничего плохого сказать в самой команде, но вы открыты для атак инъекций SQL. Кто-то может очень легко вставить «выбрать» из «DROP TABLE Orders». Если у этого человека были права, они просто уронили ваш стол. Лучший метод

exec sp_executesql @sql 

обеспечения того, чтобы @sql Юникода VARCHAR, которые вы уже сделали в вашем примере. sp_executesql также принимает аргумент параметров param, который еще более гибкий.

Также имейте в виду, если вы заявляете «Я использую .NET». У Linq есть некоторые довольно классные вещи, которые он может сделать с инфраструктурой сущностей, чтобы абстрагировать SQL из базы данных через слой модели, а также вы можете сделать динамический Linq. Это обеспечивает уровень абстракции для работы с надтоном SQL, который предпочтительнее способами, которыми вы можете моделировать свои данные с перечислениями и списками .NET, а также запускать другой код с уровня, не связанного напрямую с вашей базой данных, через весь процесс.

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