我有一个简单的声明:
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
时,获取所有没有类别过滤器的文章。
正确的解决方案是如果可能的话在客户端生成查询,并且如果参数为空则不包含该子句。如果使用 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)
索引是根据存储的值创建的,不能用于使用函数结果加速过滤。
IF @category = 0
BEGIN
SELECT * FROM Articles WHERE Category = @category
END
编辑:
您也可以这样使用 case 语句:
select * from Articles where category = (
CASE WHEN @category= 0 THEN @category END)