回答:
CASEステートメント
UPDATEを使用します。以前の構文(数人が指摘したとおり)は機能しません。CASEは次のように使用できます。
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber) = 1 THEN
@OrderNumber
ELSE
'%' + @OrderNumber
END
または、@ NJ Reedが指摘するようなIFステートメントを使用できます。
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」ロジックを適用する場合は、適用する必要のあるセクションにブールANDを使用して条件を追加するだけです。
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)SELECTの外でIFを使用する
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番目のアプローチは恐ろしいですが、そのような多数の可変条件がある場合に機能するのは、ほぼ唯一の考え方です。
IF...ELSE...
条件文をブール値AND
のとに変換することOR
です。短所^このアプローチは、多数IF
のがある場合、または多数のがネストされている場合、頭を痛めるほど難しい場合がある
IFの代わりにCASEステートメントを使用してください。
私は、... like / = ... case ... then ... then ...がBooleansで機能できると思います。T-SQLを使用しています。
シナリオ:boolがfalseの場合はPerson-30の趣味を取得し、boolがtrueの場合はPerson-42の趣味を取得するとします。(一部によると、趣味ルックアップはビジネス計算サイクルの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 OR OrderNumber = @OrderNumber) AND(IsNumber(@OrderNumber)= 1 OR OrderNumber LIKE '%' + @OrderNumber + '%')
IF P THEN Q ELSE R
<=>
( ( NOT P ) OR Q ) AND ( P OR R )
CASEステートメントは、常に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サーバーでは同じ問題がありましたが、パラメーターがfalseの場合にのみandステートメントを使用し、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