Условный оператор where T-SQL - PullRequest
       25

Условный оператор where T-SQL

3 голосов
/ 23 сентября 2011

У меня есть хранимая процедура, которая возвращает данные.

Мне нужно изменить предложение where на основе переданных параметров.

Например, параметры:

@Region NVARHCAR(15)
@CountryCode NVARCHAR(2)
@ProductA BIT
@ProductB BIT
@ProductC BIT

Если передается @Region, то где следует выбирать по региону, если @CountryCode передается, то где следует выбирать по коду страны.

Для продуктов, если какой-либо из них установлен наЗначение true, где следует выбрать данные для этого проекта.

Таким образом, оператор может выглядеть следующим образом, если передано @Region и для @ProductA и @ProductC задано значение true:

SELECT *
FROM table
WHERE Region = @Region AND
(Product = 'ProductA' OR Product = 'ProductC')

В качестве альтернативы условный продукт может быть оператором IN.

Если в него передан @CountryCode, он будет выглядеть следующим образом:

SELECT *
FROM table
WHERE CountryCode = @CountryCode AND
(Product = 'ProductA' OR Product = 'ProductC')

Возможно даже, что @CountryCode и @Region могут бытьпередано.

Есть ли способ сделать это с T-SQL, а не с динамическим SQL, сгенерированным из приложения?

Спасибо

Ответы [ 6 ]

6 голосов
/ 23 сентября 2011

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

WHERE ((@Region IS NULL) OR (Region = @Region))
AND ((@CountryCode IS NULL) OR (CountryCode = @CountryCode))
AND ((@ProductA = 0) OR (Product = 'ProductA'))
AND ((@ProductB = 0) OR (Product = 'ProductB'))
AND ((@ProductC = 0) OR (Product = 'ProductC'))

Если ваш SQL построен так, то вы фильтруете только по столбцу Region, когда передаете значение для параметра @Region.То же самое относится и к CountryCode.

2 голосов
/ 23 сентября 2011

Вы всегда можете построить оператор SQL в виде строки, используя ваши условия ... затем просто выполнить результирующую строку оператора, используя sp_executesql (команда, которая в основном выполняет оператор или пакет Transact-SQL, который может многократно использоваться повторно, илитот, который был построен динамически) ...

Я понимаю, что вы, возможно, не хотите строить строки SQL, но это решение.

2 голосов
/ 23 сентября 2011

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

ЕСЛИ НЕ @Region IS NULL ....

и иметь отдельные запросы, которые можно оптимизировать по своим достоинствам.

РЕДАКТИРОВАТЬ:

A couple principles that I think apply:

http://en.wikipedia.org/wiki/Coupling_%28computer_programming

http://en.wikipedia.org/wiki/Single_responsibility_principle

2 голосов
/ 23 сентября 2011

Это не обязательно самый чистый подход, но он позволит избежать чего-либо динамического:

SELECT *
FROM table
WHERE CountryCode = isnull(@CountryCode, CountryCode) AND
Region = isnull(@Region, Region) AND
(Product = 'ProductA' OR Product = 'ProductC')
1 голос
/ 26 сентября 2011

Во всяком случае, самый прямой подход (не обязательно самый элегантный) - установить значение по умолчанию для каждого параметра , которое не является допустимым значением параметра , и выполнить условную проверку для каждого из них, чтобы увидеть если значение, содержащееся в каждом параметре, отличается от значения по умолчанию. Здесь я предполагаю, что нулевое значение никогда не будет передано в качестве допустимого значения.

CREATE PROC sp_ProdInfo (
 @Region NVARHCAR(15) = NULL,
 @CountryCode NVARCHAR(2) = NULL,
 @ProductA BIT,
 @ProductB BIT,
 @ProductC BIT
) 
AS
 BEGIN
 -- other statements
 IF NOT @Region IS NULL
  BEGIN
   SELECT *
    FROM table
    WHERE Region = @Region AND
    (Product = 'ProductA' OR Product = 'ProductC')
  END
 ELSE
  BEGIN
   IF NOT @Country IS NULL
   BEGIN
    SELECT *
     FROM table
     WHERE CountryCode = @CountryCode AND
     (Product = 'ProductA' OR Product = 'ProductC')
   END
   ELSE
   BEGIN
    PRINT 'Neither Country nor Region was passed in.'
   END -- end inner if
  END -- end outer if
 -- other statements
 END
0 голосов
/ 23 сентября 2011

Я бы использовал общее табличное выражение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...