Можно ли использовать предложение IF в предложении WHERE в MS SQL?
Пример:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
Можно ли использовать предложение IF в предложении WHERE в MS SQL?
Пример:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
Ответы:
Используйте СЛУЧАЙ заявление
UPDATE: Предыдущий синтаксис (как было указано на несколько человек) не работает. Вы можете использовать CASE следующим образом:
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber) = 1 THEN
@OrderNumber
ELSE
'%' + @OrderNumber
END
Или вы можете использовать оператор IF, как указывает @ NJ Reed .
CASE
является подходящим решением в большинстве случаев. В моем случае я хотел изменить оператор сравнения и, следовательно, я использовал следующий подход.
Вы должны быть в состоянии сделать это без каких-либо IF или CASE
WHERE
(IsNumeric(@OrderNumber) AND
(CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
OR
(NOT IsNumeric(@OrderNumber) AND
OrderNumber LIKE ('%' + @OrderNumber))
В зависимости от разновидности SQL вам может потребоваться настроить приведение номера заказа к INT или VARCHAR в зависимости от того, поддерживаются ли неявные приведения.
Это очень распространенный метод в предложении WHERE. Если вы хотите применить некоторую логику «ЕСЛИ» в предложении WHERE, все, что вам нужно сделать, это добавить дополнительное условие с логическим И в раздел, где оно должно быть применено.
Вам не нужно заявление IF вообще.
WHERE
(IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')
where (@AdmUserId is null or CurrentOrder.CustomerAdmUserId = @AdmUserId)
Или только фильтр, если IncludeDeleted = 0: where (@IncludeDeleted = 1 or ItemObject.DeletedFlag = 0)
Нет хорошего способа сделать это в SQL. Некоторые подходы, которые я видел:
1) Используйте CASE в сочетании с логическими операторами:
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 вне SELECT
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
Третий подход отвратителен, но это почти единственная мысль, которая работает, если у вас есть несколько таких переменных условий.
IF...ELSE...
условные выражения в логические AND
и OR
как в ответе @ njr101 выше. Недостатком этого подхода является то, что это может быть чрезвычайно сложно, если у вас их много IF
, или если у вас много вложенных
Используйте оператор CASE вместо IF.
Вы хотите заявление CASE
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END
Я думаю, что где ... как / = ... case ... тогда ... может работать с логическими значениями. Я использую T-SQL.
Сценарий. Допустим, вы хотите получить увлечения Person-30, если bool имеет значение false, и увлечения Person-42, если bool имеет значение true. (По некоторым данным, хобби-поиски составляют более 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;
WHERE (IsNumeric (@OrderNumber) <> 1 ИЛИ OrderNumber = @OrderNumber) AND (IsNumber (@OrderNumber) = 1 ИЛИ OrderNumber LIKE '%' + @OrderNumber + '%')
IF P THEN Q ELSE R
<=>
( ( NOT P ) OR Q ) AND ( P OR R )
CASE Statement - лучший вариант, чем IF всегда.
WHERE vfl.CreatedDate >= CASE WHEN @FromDate IS NULL THEN vfl.CreatedDate ELSE @FromDate END
AND vfl.CreatedDate<=CASE WHEN @ToDate IS NULL THEN vfl.CreatedDate ELSE @ToDate END
WHERE OrderNumber LIKE CASE WHEN IsNumeric(@OrderNumber) = 1 THEN @OrderNumber ELSE '%' + @OrderNumber END
В случае строки Условие будет работать правильно.
В следующем примере выполняется запрос как часть логического выражения, а затем выполняются несколько другие блоки операторов в зависимости от результата логического выражения. Каждый блок операторов начинается с 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
В SQL Server у меня была та же проблема, я хотел использовать оператор and, только если параметр имеет значение false и на true мне пришлось показывать оба значения true и false, поэтому я использовал его таким образом
(T.IsPublic = @ShowPublic or @ShowPublic = 1)
If @LstTransDt is Null
begin
Set @OpenQty=0
end
else
begin
Select @OpenQty=IsNull(Sum(ClosingQty),0)
From ProductAndDepotWiseMonitoring
Where Pcd=@PCd And PtpCd=@PTpCd And TransDt=@LstTransDt
end
Посмотрите, поможет ли это.
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