我正在创建一个存储过程来返回搜索结果,其中一些参数是可选的。
我想在 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
任何想法如何做到这一点?
答案 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语句。这对我有用。