14

一部のパラメーターがオプションである検索結果を返すストアド プロシージャを作成しています。

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

これを行う方法はありますか?

4

5 に答える 5

25
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))
于 2008-11-25T13:48:36.840 に答える
1

あなたが話しているように、私たちCOALESCEは過去にここで「動的なWHERE句」をたくさん使ってきました。

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))
于 2008-11-25T14:16:56.860 に答える
0

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

于 2008-11-25T13:59:49.687 に答える
0

IF は T-SQl の手続き型コードです。挿入/更新/削除/選択ステートメントでは使用できません。2 つのステートメントのどちらを実行するかを決定するためにのみ使用できます。ステートメント内でさまざまな可能性が必要な場合は、上記のようにするか、CASE ステートメントを使用できます。

于 2008-11-25T14:35:42.483 に答える
-2

IF ステートメントを SQL ステートメント全体に配置してみてください。つまり、条件ごとに 1 つの SQL ステートメントを持つことになります。それは私のために働いた。

于 2009-12-30T17:54:09.560 に答える