用于搜索数据库的where子句中的SQL if语句

时间:2008-11-25 13:45:26

标签: sql-server tsql stored-procedures filtering if-statement

我正在创建一个存储过程来返回搜索结果,其中一些参数是可选的。

我想在 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

任何想法如何做到这一点?

5 个答案:

答案 0 :(得分: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))

答案 1 :(得分: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)  

这与Michael上面提出的建议相同......

IsNull()和Coalesce()或多或少地以相同的方式工作,它们返回列表中的第一个非Null参数,除了iSNull只允许2个参数,Coalesce可以接受任何数字...

http://blogs.msdn.com/sqltips/archive/2008/06/26/differences-between-isnull-and-coalesce.aspx

答案 2 :(得分:0)

我们过去曾在{{{}}}使用了很多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),那么该行甚至不会显示在结果中(如果您的过滤器是可选的,则是不正确的排他行为)。

为了弥补可以为空的字段,你最终不得不像这样做看起来更糟糕的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))

答案 3 :(得分:0)

您理解,IF是T-SQl中的程序代码。它可以在insert / update / delete / select语句中使用,它只能用于确定要运行的两个语句中的哪一个。当您在语句中需要不同的可能性时,您可以执行上述操作或使用CASE语句。

答案 4 :(得分:-2)

尝试将IF语句放在整个SQL语句中。这意味着每个条件都有一个SQL语句。这对我有用。