【问题标题】:Using a tristate parameter in a stored procedure在存储过程中使用三态参数
【发布时间】:2008-10-10 15:46:22
【问题描述】:
这样做的正确方法是什么?例如,我将如何更改具有此签名的存储过程:
CREATE PROCEDURE dbo.MyProcedure
@Param BIT = NULL
AS
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = @Param
所以给@Param 赋值 1 或 0 执行过滤,但不指定它或传递 NULL 不执行过滤?
【问题讨论】:
标签:
sql
stored-procedures
【解决方案1】:
假设 NULL 表示“不关心”然后使用
CREATE PROCEDURE dbo.MyProcedure
@Param BIT = NULL
AS
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = @Param OR @Param IS NULL
【解决方案2】:
方法不止一种。这是一个:
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = COALESCE(@Param, T.SomeColumn)
但这不包括 T.SomeColumn 为 NULL 的行。
以下替代方案将包括这些行:
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = @Param OR @Param IS NULL
但它有重复参数的缺点,如果您使用其他方式传递参数,例如使用占位符,这并不好。
【解决方案3】:
我碰巧认为最简洁的方法是(在 T-SQL 中)是:
SELECT * FROM TABLE WHERE column = ISNULL(@param, column)
其他 RDBMS 更喜欢 COALESCE 而不是 ISNULL。
我认为这里的意图更明显,尤其是当您开始添加其他 OR 子句时,它还使您在与 AND 子句组合时不需要括号。
在我(非常)有限的测试中,使用 ISNULL 与 OR @p IS NULL 相比,性能提升也可以忽略不计。并不是说我提倡使用 ISNULL 因为的性能增加(这充其量是极其微不足道的,并且在最坏的情况下受到非常具体的情况的影响)但很高兴知道它没有显着成本。坦率地说,我不确定为什么这两种方法都会有所不同,但执行计划显示过滤器成本大约有 1% 的差异。