Построение динамического в утверждениях с SQL - PullRequest
2 голосов
/ 15 марта 2010

Предположим, нам нужно проверить три логических условия для выполнения запроса выбора. Пусть три флага будут «A», «B» и «C».

Если все три флага установлены в «1», то запрос, который будет сгенерирован, ВЫБРАТЬ * ИЗ ПИТАНИЯ, ГДЕ Имя В («Яблоко», «Бисквит», «Шоколад»); Если только флаги «A» и «B» установлены в «1», а «C» - в «0». Затем генерируется следующий запрос.

SELECT * 
  FROM Food 
 WHERE Name In ('Apple, 'Biscuit');

Каков наилучший способ сделать это?

Ответы [ 5 ]

2 голосов
/ 15 марта 2010
SELECT * 
  FROM Food
 WHERE (Name = 'Apple' AND <condition A>)
    OR (Name = 'Biscuit' AND <condition B>)
    OR (Name = 'Chocolate' AND <condition C>)

Теперь, будучи корректным, это нежелательно с точки зрения производительности, поскольку условия A, B и C не управляются данными (они не меняются от строки к строке).Таким образом, вы можете использовать перестановки всех возможных условий, динамически создавая SQL - используйте предложение IN и динамически создавайте его строку.

Еще одно решение - это сборка конечного результата в клиенте путем запуска каждого SELECT отдельно (псевдокод):

if A then {
   result1 = execute("SELECT * FROM Food WHERE Name = 'Apple')
}
if B then {
   result2 = execute("SELECT * FROM Food WHERE Name = 'Biscuit')
}
if C then {
   result2 = execute("SELECT * FROM Food WHERE Name = 'Chocolate')
}

result = join(result1, result2, result3)

Это решение может работать, если у вас высокий процент случаев с одним или двумя истинными условиями.

0 голосов
/ 15 марта 2010

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

Условия динамического поиска в T-SQL

Проклятие и благословения динамического SQL

0 голосов
/ 15 марта 2010

Почему вы не включили A / B / C в запрос? выберите * из пищи, где (имя = «яблоко» или НЕ А) и (имя = «печенье» ИЛИ НЕ Б) ...

0 голосов
/ 15 марта 2010

Я думаю, что это должно быть прочитано: Динамический SQL .

Системная хранимая процедура sp_executesql также очень полезна.

0 голосов
/ 15 марта 2010

Сначала может потребоваться проверить, все ли ложные, и показать ошибку. Или может не быть, если это приемлемо в вашем случае.

Тогда, если эти флаги являются просто переменными bool, делайте (псевдокод)

sql = "SELECT * 
  FROM Food 
 WHERE Name In (";
if (A) sql += "'Apple', "
if (B) sql += "'Biscuit', "
if (C) sql += "'Chocolate', "
sql = sql.deleteLastCharacter() + ");";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...