1

我有存储过程采用多个参数(在某些情况下最多 7 或 8 个)用于过滤结果集。这些参数是可选的(默认NULL)。传入的所有非 NULL 值都将在过滤器中使用(即它是 booleanand而不是 boolean or)。

这些查询通常最终看起来像这样......

SELECT *
FROM [MyTable]
WHERE (@Param1 IS NULL OR (@Param1 IS NOT NULL AND [Field1] = @Param1))
      AND (@Param2 IS NULL OR (@Param2 IS NOT NULL AND [Field2] = @Param2))
      AND (@Param3 ...

我知道这是非常低效的,但是由于参数的数量,它不可能将它们分成单独的查询。

因此,我尝试执行以下操作...

SELECT *
FROM [MyTable]
WHERE [Field1] = ISNULL(@Param1, [Field1])
      AND [Field2] = ISNULL(@Param2, [Field2])
      AND [Field3] ...

但是,当字段包含时会出现问题NULL,因此=运算符根本不起作用。

有没有一种简单而有效的方法来做到这一点,以便我可以使用多个“过滤器”参数进行单个查询?如果可能的话,我宁愿不使用动态 SQL。

4

2 回答 2

1

好吧,您可以将初始 SQL 简化为这个,因为您已经NULL在每个子句中进行了测试。

SELECT *
FROM [MyTable]
WHERE (@Param1 IS NULL OR [Field1] = @Param1)
      AND (@Param2 IS NULL OR [Field2] = @Param2)
      AND (@Param3 ...

这不一定是低效的。如果您经常传入导致执行计划大相径庭的参数组合,您可能会明智地检查参数嗅探问题。

于 2012-09-11T16:22:09.477 回答
0

使用“is null”的替代方法是进行此比较:

where coalesce(Field1, @Param1, '') = coalesce(@Param1, Field1, '') . . .

如果 Field1 或 @Param1 之一具有值,则两个 COALESCE 返回该值。只有当两者都为 NULL 时,你才能进入第三个参数。

It so happens that you can convert '' to any type, so that is also covered. However, the use of the function tends to preclude the user of indexes.

于 2012-09-11T18:52:21.193 回答