Ist es möglich, eine IF- Klausel innerhalb einer WHERE- Klausel in MS SQL zu verwenden?
Beispiel:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
Ist es möglich, eine IF- Klausel innerhalb einer WHERE- Klausel in MS SQL zu verwenden?
Beispiel:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
Antworten:
Verwenden Sie eine CASE- Anweisung.
UPDATE: Die vorherige Syntax (auf die einige Leute hingewiesen haben) funktioniert nicht. Sie können CASE wie folgt verwenden:
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber) = 1 THEN
@OrderNumber
ELSE
'%' + @OrderNumber
END
Oder Sie können eine IF-Anweisung verwenden, wie @ NJ Reed hervorhebt.
CASE
In den meisten Fällen ist die Verwendung die geeignete Lösung. In meinem Fall wollte ich den Vergleichsoperator ändern und habe daher den nächsten Ansatz verwendet.
Sie sollten dies ohne IF oder CASE tun können
WHERE
(IsNumeric(@OrderNumber) AND
(CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
OR
(NOT IsNumeric(@OrderNumber) AND
OrderNumber LIKE ('%' + @OrderNumber))
Abhängig von der SQL-Variante müssen Sie möglicherweise die Casts auf der Bestellnummer auf INT oder VARCHAR anpassen, je nachdem, ob implizite Casts unterstützt werden.
Dies ist eine sehr häufige Technik in einer WHERE-Klausel. Wenn Sie eine "IF" -Logik in der WHERE-Klausel anwenden möchten, müssen Sie lediglich die zusätzliche Bedingung mit einem booleschen UND zu dem Abschnitt hinzufügen, in dem sie angewendet werden muss.
Sie brauchen überhaupt keine IF-Anweisung.
WHERE
(IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')
where (@AdmUserId is null or CurrentOrder.CustomerAdmUserId = @AdmUserId)
Oder nur filtern, wenn IncludeDeleted = 0: where (@IncludeDeleted = 1 or ItemObject.DeletedFlag = 0)
In SQL gibt es keine gute Möglichkeit, dies zu tun. Einige Ansätze, die ich gesehen habe:
1) Verwenden Sie CASE in Kombination mit booleschen Operatoren:
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) Verwenden Sie IFs außerhalb von SELECT
IF (IsNumeric(@OrderNumber)) = 1
BEGIN
SELECT * FROM Table
WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
SELECT * FROM Table
WHERE OrderNumber LIKE '%' + @OrderNumber
END
3) Verfassen Sie Ihre SQL-Anweisung mit einer langen Zeichenfolge unter bestimmten Bedingungen und verwenden Sie dann EXEC
Der dritte Ansatz ist abscheulich, aber es ist fast der einzige Gedanke, der funktioniert, wenn Sie eine Reihe von variablen Bedingungen wie diese haben.
IF...ELSE...
conditionals in boolean AND
‚s und OR
‘ s wie in @ njr101 Antwort oben. Der Nachteil dieses Ansatzes ist, dass es schwierig sein kann, wenn Sie viele haben IF
oder wenn viele verschachtelt sind
Verwenden Sie eine CASE- Anweisung anstelle von IF.
Sie möchten die CASE-Anweisung
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END
Ich denke, wo ... wie / = ... Fall ... dann ... mit Booleschen Werten arbeiten kann. Ich benutze T-SQL.
Szenario: Angenommen, Sie möchten die Hobbys von Person-30 erhalten, wenn bool falsch ist, und die Hobbys von Person-42, wenn bool wahr ist. (Laut einigen machen Hobby-Lookups über 90% der Geschäftsberechnungszyklen aus, zahlen Sie also genau.)
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 OR OrderNumber = @OrderNumber) AND (IsNumber (@OrderNumber) = 1 ODER OrderNumber LIKE '%' + @OrderNumber + '%')
IF P THEN Q ELSE R
<=>
( ( NOT P ) OR Q ) AND ( P OR R )
CASE Statement ist immer eine bessere Option als 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
In diesem Fall funktioniert der Zustand ordnungsgemäß.
Im folgenden Beispiel wird eine Abfrage als Teil des Booleschen Ausdrucks ausgeführt und anschließend basierend auf dem Ergebnis des Booleschen Ausdrucks geringfügig andere Anweisungsblöcke ausgeführt. Jeder Anweisungsblock beginnt mit BEGIN und endet mit 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
Verwenden verschachtelter IF ... ELSE-Anweisungen Das folgende Beispiel zeigt, wie eine IF ... ELSE-Anweisung in einer anderen verschachtelt werden kann. Setzen Sie die Variable @Number auf 5, 50 und 500, um jede Anweisung zu testen.
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
In SQL Server hatte ich das gleiche Problem, dass ich eine and-Anweisung nur verwenden wollte, wenn der Parameter false ist, und bei true musste ich beide Werte true und false anzeigen, damit ich sie auf diese Weise verwendete
(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
Sehen Sie, ob dies hilft.
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