首先,请将此代码段作为示例:
SELECT *
FROM StatsVehicle
WHERE ((ReferenceMakeId = @referenceMakeId)
OR @referenceMakeId IS NULL)
如果变量@referenceMakeId不为null,则将获取并过滤记录;如果变量为null,则将获取所有记录。换句话说,如果@referenceMakeId不为空,则考虑第一个。
我想对此添加进一步的限制,我该如何实现?
例如
(ReferenceModelId = @referenceModeleId) OR
(
(ReferenceMakeId = @referenceMakeId) OR
(@referenceMakeId IS NULL)
)
如果@referenceModelId不为null,则只需要按ReferenceModelId进行过滤,并忽略其中的其他语句。如果我实际上这样做,它将返回所有记录。有什么办法可以做到这一点吗?
答案 0 :(得分:1)
也许是这样的?
SELECT * FROM StatsVehicle WHERE
(
-- Removed the following, as it's not clear if this is beneficial
-- (@referenceModeleId IS NOT NULL) AND
(ReferenceModelId = @referenceModeleId)
) OR
(@referenceModeleId IS NULL AND
(
(ReferenceMakeId = @referenceMakeId) OR
(@referenceMakeId IS NULL)
)
)
答案 1 :(得分:0)
这应该可以解决问题。
SELECT * FROM StatsVehicle
WHERE ReferenceModelId = @referenceModeleId OR
(
@referenceModeleId IS NULL AND
(
@referenceMakeId IS NULL OR
ReferenceMakeId = @referenceMakeId
)
)
但是,您应该注意,这种类型的查询(称为catch-all查询)往往效率低于为每个案例编写单个查询。
这是因为SQL Server将缓存可能不是其他参数最佳的第一个查询计划。
您可能需要考虑使用OPTION (RECOMPILE)
query hint,或者将存储过程制动为每个处理特定条件的片段(即一个选择空值变量,一个选择非空值)。
有关详情,请参阅this article。
答案 2 :(得分:0)
如果@referenceModelId不为null,则只需要过滤 ReferenceModelId,并忽略其中的其他语句。如果我 实际上这样做,它返回所有记录。在那儿 什么都可以做到这一点?
您可以考虑使用CASE
来获得良好的短路机制
WHERE
CASE
WHEN @referenceModelId is not null AND ReferenceModelId = @referenceModeleId THEN 1
WHEN @referenceMakeId is not null AND ReferenceMakeId = @referenceMakeId THEN 1
WHEN @referenceModelId is null AND @referenceMakeId is null THEN 1
ELSE 0
END = 1