MS SQL'de bir WHERE yan tümcesi içinde bir IF yan tümcesi kullanmak mümkün mü ?
Misal:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
MS SQL'de bir WHERE yan tümcesi içinde bir IF yan tümcesi kullanmak mümkün mü ?
Misal:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
Yanıtlar:
Bir CASE deyimi kullanın
GÜNCELLEME: Önceki sözdizimi (birkaç kişi tarafından işaret edildiği gibi) çalışmaz. CASE'i aşağıdaki gibi kullanabilirsiniz:
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber) = 1 THEN
@OrderNumber
ELSE
'%' + @OrderNumber
END
Veya @ NJ Reed'in işaret ettiği gibi bir IF deyimini kullanabilirsiniz .
CASE
Çoğu durumda kullanmak uygun çözümdür. Benim durumumda, karşılaştırma operatörünü değiştirmek istedim ve dolayısıyla bir sonraki yaklaşımı kullandım.
Bunu herhangi bir IF veya CASE olmadan yapabilmelisiniz
WHERE
(IsNumeric(@OrderNumber) AND
(CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
OR
(NOT IsNumeric(@OrderNumber) AND
OrderNumber LIKE ('%' + @OrderNumber))
SQL'in lezzetine bağlı olarak, sipariş numarasındaki dökümleri, örtülü dökümlerin desteklenip desteklenmemesine bağlı olarak bir INT veya VARCHAR'a ayarlamanız gerekebilir.
Bu bir WHERE yan tümcesinde çok yaygın bir tekniktir. WHERE yan tümcesine bir "IF" mantığı uygulamak istiyorsanız, tek yapmanız gereken, boolean AND ile ekstra koşulu uygulanması gereken bölüme eklemektir.
Bir IF deyimine ihtiyacınız yoktur.
WHERE
(IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')
where (@AdmUserId is null or CurrentOrder.CustomerAdmUserId = @AdmUserId)
varsa filtreleyin : Veya yalnızca IncludeDeleted = 0 ise filtreleyin:where (@IncludeDeleted = 1 or ItemObject.DeletedFlag = 0)
Bunu SQL'de yapmanın iyi bir yolu yoktur. Gördüğüm bazı yaklaşımlar:
1) Boole operatörleriyle birlikte CASE kullanın:
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) SELECT dışındaki IF'leri kullanın
IF (IsNumeric(@OrderNumber)) = 1
BEGIN
SELECT * FROM Table
WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
SELECT * FROM Table
WHERE OrderNumber LIKE '%' + @OrderNumber
END
3) Uzun bir dize kullanarak, SQL ifadenizi koşullu olarak oluşturun ve EXEC kullanın
3. yaklaşım iğrençtir, ancak böyle bir dizi değişken koşulunuz varsa işe yarayan neredeyse tek düşüncedir.
IF...ELSE...
koşullarınızı yukarıdaki @ njr101 yanıtında olduğu gibi boole AND
ve s'ye dönüştürmektir OR
. ^ Bu yaklaşımın dezavantajı, çok sayıda IF
varsa veya yuvalanmış çok sayıda varsa, beyin kızartma zor olabilir
IF yerine bir CASE deyimi kullanın.
CASE deyimini istiyorsunuz
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END
Sanırım ... = / case gibi ... o zaman ... Boolean'larla çalışabilir. T-SQL kullanıyorum.
Senaryo: Diyelim ki bool yanlışsa Person-30'un hobilerini, bool doğru ise Person-42'nin hobilerini almak istiyorsunuz. (Bazılarına göre, hobi aramaları iş hesaplama döngülerinin% 90'ından fazlasını oluşturur, bu nedenle yakın ödeme yapın.).
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;
NEREDE (IsNumeric (@OrderNumber) <> 1 VEYA OrderNumber = @OrderNumber) AND (IsNumber (@OrderNumber) = 1 VEYA OrderNumber '%' GİBİ + @OrderNumber + '%')
IF P THEN Q ELSE R
<=>
( ( NOT P ) OR Q ) AND ( P OR R )
CASE deyimi her zaman IF'den daha iyi bir seçenektir .
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
Bu durumda Durum düzgün çalışacaktır.
Aşağıdaki örnek, Boole ifadesinin bir parçası olarak bir sorgu yürütür ve ardından Boolean ifadesinin sonucuna bağlı olarak biraz farklı ifade blokları yürütür. Her ifade bloğu BEGIN ile başlar ve END ile tamamlanır.
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
İç içe IF ... ELSE deyimlerini kullanma Aşağıdaki örnek, bir IF… ELSE deyiminin diğerinin içine nasıl yerleştirilebileceğini gösterir. Her bir ifadeyi test etmek için @Number değişkenini 5, 50 ve 500 olarak ayarlayın.
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 sunucusunda ben sadece parametre yanlış ve doğru ise bir ve deyimi kullanmak istedim aynı sorunu vardı doğru ve yanlış her iki değeri göstermek zorunda böylece bu şekilde kullanılır
(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
Bunun yardımcı olup olmadığını görün.
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