一部のパラメーターがオプションである検索結果を返すストアドプロシージャを作成しています。
where句に「ifステートメント」が必要ですが、機能しません。 where句は、null以外のパラメータのみでフィルタリングする必要があります。
ここにspがあります
ALTER PROCEDURE spVillaGet
-- Add the parameters for the stored procedure here
@accomodationFK int = null,
@regionFK int = null,
@arrivalDate datetime,
@numberOfNights int,
@sleeps int = null,
@priceFloor money = null,
@priceCeil money = null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
select tblVillas.*, tblWeeklyPrices.price from tblVillas
INNER JOIN tblWeeklyPrices on tblVillas.villaId = tblWeeklyPrices.villaFK
where
If @accomodationFK <> null then
accomodationTypeFK = @accomodationFK
@regionFK <> null Then
And regionFK = @regionFK
IF @sleeps <> null Then
And sleeps = @sleeps
IF @priceFloor <> null Then
And price >= @priceFloor And price <= @priceCeil
END
これを行う方法のアイデアはありますか?
select tblVillas.*, tblWeeklyPrices.price
from tblVillas
INNER JOIN tblWeeklyPrices on tblVillas.villaId = tblWeeklyPrices.villaFK
where (@accomodationFK IS null OR accomodationTypeFK = @accomodationFK)
AND (@regionFK IS null or regionFK = @regionFK)
AND (@sleeps IS null OR sleeps = @sleeps)
AND (@priceFloor IS null OR (price BETWEEN @priceFloor And @priceCeil))
あなたが話しているように、過去にここで「 動的WHERE句 "」に多くのCOALESCE
を使用しました。
SELECT *
FROM vehicles
WHERE ([vin] LIKE COALESCE(@vin, [vin]) + '%' ESCAPE '\')
AND ([year] LIKE COALESCE(@year, [year]) + '%' ESCAPE '\')
AND ([make] LIKE COALESCE(@make, [make]) + '%' ESCAPE '\')
AND ([model] LIKE COALESCE(@model, [model]) + '%' ESCAPE '\')
ただし、オプションでnull許容の列をフィルタリングする場合、大きな問題が発生します...列のデータが特定の行のnull
であり、ユーザーが検索するものを何も入力しなかった場合その列(つまり、ユーザー入力もnull
)の場合、その行は結果にも表示されません(これは、フィルタがオプションの場合、除外動作は正しくありません)。
Null許容フィールドを補正するために、次のように乱雑に見えるSQLを実行する必要があります。
SELECT *
FROM vehicles
WHERE (([vin] LIKE COALESCE(@vin, [vin]) + '%' ESCAPE '\')
OR (@vin IS NULL AND [vin] IS NULL))
AND (([year] LIKE COALESCE(@year, [year]) + '%' ESCAPE '\')
OR (@year IS NULL AND [year] IS NULL))
AND (([make] LIKE COALESCE(@make, [make]) + '%' ESCAPE '\')
OR (@make IS NULL AND [make] IS NULL))
AND (([model] LIKE COALESCE(@model, [model]) + '%' ESCAPE '\')
OR (@model IS NULL AND [model] IS NULL))
ご理解いただけると思いますが、IFはT-SQlの手続き型コードです。挿入/更新/削除/選択ステートメントでは使用できません。2つのステートメントのどちらを実行するかを決定するためにのみ使用できます。ステートメント内でさまざまな可能性が必要な場合は、上記のようにするか、CASEステートメントを使用できます。
IsNullまたはCoalesce関数を使用することもできます
Where accomodationTypeFK = IsNull(@accomodationFK, accomodationTypeFK)
And regionFK = Coalesce(@regionFK,regionFK)
And sleeps = IsNull(@sleeps,sleeps )
And price Between IsNull(@priceFloor, Price) And IsNull(priceCeil, Price)
これは、上記のマイケルの提案と同じことをします...
IsNull()とCoalesce()はほぼ同じように動作しますが、リストの最初の非null引数を返しますが、iSNullは2つの引数しか許可せず、Coalesceは任意の数を取ることができます...
http://blogs.msdn.com/sqltips/archive/2008/06/26/differences-between-isnull-and-coalesce.aspx