2008-09-17 2 views

ответ

167

Используйте CASE заявление
UPDATE: Предыдущий синтаксис (как было указано на несколько человек) не работает. Вы можете использовать СЛУЧАЙ следующим образом:

WHERE OrderNumber LIKE 
    CASE WHEN IsNumeric(@OrderNumber) = 1 THEN 
    @OrderNumber 
    ELSE 
    '%' + @OrderNumber 
    END 

Или вы можете использовать оператор IF, как @N. J. Reed указывает.

+0

[Замечание после UPDATE by author]: Это должно работать, но вы должны TRIM() обеими сторонами, чтобы убедиться, что совпадение найдено. У меня есть ощущение, что есть редкие случаи, которые не совпадают. – 2008-09-17 21:51:18

+1

Использование `CASE` является подходящим решением в большинстве случаев. В моем случае я хотел изменить оператор сравнения, и поэтому я использовал следующий подход. – Birla 2014-11-15 11:59:56

6

Используйте CASE заявление вместо IF.

4

вы хотите сазе

WHERE OrderNumber LIKE 
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END 
117

Вы должны быть в состоянии сделать это без каких-либо IF или ДЕЛУ

WHERE 
    (IsNumeric(@OrderNumber) AND 
     (CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR) 
OR 
    (NOT IsNumeric(@OrderNumber) AND 
     OrderNumber LIKE ('%' + @OrderNumber)) 

В зависимости от вкуса SQL вам может потребоваться настроить слепки на номер заказа в INT или VARCHAR в зависимости от того, поддерживаются ли имплицитные приведения.

Это очень распространенная техника в предложении WHERE. Если вы хотите применить некоторую логику «IF» в предложении WHERE, все, что вам нужно сделать, это добавить дополнительное условие с булевым И в раздел, где он должен применяться.

+1

Я бы предположил, что вы немного поработали над решением CASE, так как все эти условия оцениваются, нет? – 2008-09-26 13:06:37

+0

Perfect - решена давняя проблема для меня; спасибо за указатель! – cori 2009-05-12 15:35:28

+0

Я всегда забываю, что в SQL можно заменить условные операторы логической логикой. Спасибо за напоминание, это очень полезная техника! – CodexArcanum 2010-10-08 16:05:07

13

В SQL нет хорошего способа сделать это. Некоторые подходы, которые я видел:

1) Используйте СЛУЧАЙ в сочетании с логическими операторами:

WHERE 
    OrderNumber = CASE 
     WHEN (IsNumeric(@OrderNumber) = 1) 
     THEN CONVERT(INT, @OrderNumber) 
     ELSE -9999 -- Some numeric value that just cannot exist in the column 
    END 
    OR 
    FirstName LIKE CASE 
     WHEN (IsNumeric(@OrderNumber) = 0) 
     THEN '%' + @OrderNumber 
     ELSE '' 
    END 

2) Использование ИФ вне ВЫБОР

IF (IsNumeric(@OrderNumber)) = 1 
BEGIN 
    SELECT * FROM Table 
    WHERE @OrderNumber = OrderNumber 
END ELSE BEGIN 
    SELECT * FROM Table 
    WHERE OrderNumber LIKE '%' + @OrderNumber 
END 

3) Используя длинную строку, составить свой SQL заявление условно, а затем использовать EXEC

3-й подход является отвратительным, но это почти единственное мнение, которое работает, если у вас есть несколько переменных условий, подобных этому.

3

Я думаю, что где ... как/= ... случай ... тогда ... может работать с булевыми. Я использую T-SQL.

Сценарий: Предположим, вы хотите получить хобби Person-30, если bool является ложным, а хобби Person-42, если bool истинно. (По мнению некоторых, хобби-поиски составляют более 90% циклов бизнес-вычислений, поэтому платите близко).

CREATE PROCEDURE sp_Case 
@bool bit 
AS 
SELECT Person.Hobbies 
FROM Person 
WHERE Person.ID = 
    case @bool 
     when 0 
      then 30 
     when 1 
      then 42 
    end; 
1
 
WHERE (IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber) 
      AND (IsNumber(@OrderNumber) = 1 OR OrderNumber LIKE '%' 
               + @OrderNumber + '%') 
-6
USE AdventureWorks2012; 
GO 
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%') > 5 
PRINT 'There are more than 5 Touring-3000 bicycles.' 
ELSE PRINT 'There are 5 or less Touring-3000 bicycles.' ; 
GO 
0

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

USE AdventureWorks2012; 
GO 
DECLARE @AvgWeight decimal(8,2), @BikeCount int 
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%') > 5 
BEGIN 
    SET @BikeCount = 
     (SELECT COUNT(*) 
     FROM Production.Product 
     WHERE Name LIKE 'Touring-3000%'); 
    SET @AvgWeight = 
     (SELECT AVG(Weight) 
     FROM Production.Product 
     WHERE Name LIKE 'Touring-3000%'); 
    PRINT 'There are ' + CAST(@BikeCount AS varchar(3)) + ' Touring-3000 bikes.' 
    PRINT 'The average weight of the top 5 Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.'; 
END 
ELSE 
BEGIN 
SET @AvgWeight = 
     (SELECT AVG(Weight) 
     FROM Production.Product 
     WHERE Name LIKE 'Touring-3000%'); 
    PRINT 'Average weight of the Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.' ; 
END ; 
GO 

Использование вложенных IF ... ELSE утверждения В следующем примере показано, как IF ... ELSE оператор может быть вложен в другой. Установите для переменной @Number 5, 50 и 500 для проверки каждого утверждения.

DECLARE @Number int 
SET @Number = 50 
IF @Number > 100 
    PRINT 'The number is large.' 
ELSE 
    BEGIN 
     IF @Number < 10 
     PRINT 'The number is small' 
    ELSE 
     PRINT 'The number is medium' 
    END ; 
GO 
12

Вам не нужен оператор IF вообще.

WHERE 
    (IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber) 
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%') 
Смежные вопросы