我有一个存储过程,它接收3个用于动态过滤结果集的参数
create proc MyProc
@Parameter1 int,
@Parameter2 int,
@Paremeter3 int
as
select * from My_table
where
1 = case when @Parameter1 = 0 then 1 when @Parameter1 = Column1 then 1 else 0 end
and
1 = case when @Parameter2 = 0 then 1 when @Parameter2 = Column2 then 1 else 0 end
and
1 = case when @Parameter3 = 0 then 1 when @Parameter3 = Column3 then 1 else 0 end
return
为每个参数传递的值可以是0(对于所有项目),对于在特定列上匹配的项目,可以是非零。
我可能有超过20个参数(示例仅显示3个)。是否有更优雅的方法允许在数据库变大时进行扩展?
答案 0 :(得分:0)
我正在使用与您的想法相似的东西:
select *
from TableA
where
(@Param1 is null or Column1 = @Param1)
AND (@Param2 is null or Column2 = @Param2)
AND (@Param3 is null or Column3 = @Param3)
它通常是相同的,但我使用NULL作为中性值而不是0.在某种意义上它更灵活,@Param变量的数据类型无关紧要。
答案 1 :(得分:0)
我使用了与上面列出的一些略有不同的方法,但我没有注意到任何性能损失。我没有过滤0而没有过滤器,而是使用null,我会强制它成为参数的默认值。
当我们给出参数默认值时,它使它们成为可选的,这使得在调用过程时更好的可读性。
create proc myProc
@Parameter1 int = null,
@Parameter2 int = null,
@Paremeter3 int = null
AS
select
*
from
TableA
where
column1 = coalesce(@Parameter1,column1)
and
column2 = coalesce(@Parameter2, column2)
and
column3 = coalesce(@Parameter3,column3)
那说我下次可能会尝试使用动态sql方法来查看是否有任何性能差异
答案 2 :(得分:0)
不幸的是,动态SQL 是明智的解决方案性能/稳定性。虽然常用的所有其他方法(@param is not or Col = @param
,COALESCE
,CASE
...)都可以使用,但它们是不可预测且不可靠的,执行计划可以(并且会)因每次执行而异可能会发现自己花了很多时间试图弄明白,为什么你的查询在昨天工作正常时表现非常糟糕。