如何忽略 SQL 语句中的 WHERE [重复]

问题描述 投票:0回答:2

我有一个简单的声明:

SELECT *  
FROM Articles 
WHERE Category = @category

@category
0
null
时,我需要忽略
WHERE
条件并SQL选择所有文章;类似于以下声明:

SELECT * 
FROM Articles
IF @category = 0 
BEGIN
WHERE Category = @category
END

我想按类别获取文章,但是当

@category
null
0
时,获取所有没有类别过滤器的文章。

sql sql-server stored-procedures conditional-statements
2个回答
2
投票

正确的解决方案是如果可能的话在客户端生成查询,并且如果参数为空则不包含该子句。如果使用 LINQ(例如使用 EF Core),则可以轻松地一次构建一个查询的一部分:

var query=context.Articles.AsQueryable();
if(categoryId>0)
{
    query=query.Where(a=>a.CategoryId=categoryId);
}

在 SQL 中,无法将 NULL 与任何其他值(甚至 NULL)进行比较,因此需要使用 IS NULL。

SELECT *  
FROM Articles 
WHERE (Category = @category OR @category IS NULL or @category=0)
OPTION (RECOMPILE)

OPTION (RECOMPILE)
部分很重要。数据库将查询编译成执行计划并重用它们,而不是一直重新编译。这可以节省大量时间和内存,尤其是在繁忙的系统上。如果没有 OPTION(RECOMPILE),服务器将重用第一次调用时生成的相同执行计划。如果
@category
为空,则执行计划将扫描整个表,而不是使用覆盖
Category
 的任何索引
这应该

被使用,因为它完全阻止了索引的使用: ISNULL(Category,0)=ISNULL(@category,0)

索引是根据存储的值创建的,不能用于使用函数结果加速过滤。


-2
投票

IF @category = 0 BEGIN SELECT * FROM Articles WHERE Category = @category END

编辑:

您也可以这样使用 case 语句:

select * from Articles where category = ( CASE WHEN @category= 0 THEN @category END)

	
© www.soinside.com 2019 - 2024. All rights reserved.