Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2005 使用ISNULL的可选where子句_Sql Server 2005 - Fatal编程技术网

Sql server 2005 使用ISNULL的可选where子句

Sql server 2005 使用ISNULL的可选where子句,sql-server-2005,Sql Server 2005,我让存储过程使用多个参数(在某些情况下最多7或8个)来过滤结果集。这些参数是可选的(默认值NULL)。所有传入的非空值都将在筛选器中使用(即,它是布尔值和,而不是布尔值或) 这些查询结果通常是这样的 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

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

这些查询结果通常是这样的

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。

好吧,您可以将初始SQL简化为以下内容,因为您已经在每个子句中测试了
NULL

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

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

那么,您可以将初始SQL简化为这一点,因为您已经在每个子句中测试了
NULL

SELECT *
FROM [MyTable]
WHERE (@Param1 IS NULL OR [Field1] = @Param1)
      AND (@Param2 IS NULL OR [Field2] = @Param2)
      AND (@Param3 ...
这并不一定是低效的。如果您经常传入导致执行计划大不相同的参数组合,您可能会明智地检查参数嗅探问题。

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

where coalesce(Field1, @Param1, '') = coalesce(@Param1, Field1, '') . . .
如果Field1或@Param1中有一个有值,则两个合并返回该值。只有当两者都为NULL时,才能进入第三个参数

碰巧,您可以将
'
转换为任何类型,因此也包括了这一点。但是,使用该函数往往会排除索引的用户。

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

where coalesce(Field1, @Param1, '') = coalesce(@Param1, Field1, '') . . .
如果Field1或@Param1中有一个有值,则两个合并返回该值。只有当两者都为NULL时,才能进入第三个参数


碰巧,您可以将
'
转换为任何类型,因此也包括了这一点。然而,函数的使用倾向于排除索引的用户。

是的,公平点,我认为这是一个悬念,因为参数过去是实际值而不是空值。。。例如,它们过去是
和(@Param1=''或(@Param1''和[Field1]=@Param1))
。由于SQL不像C#
和&
或VB.NET
那样做短路,所以我认为这是必要的。是的,公平的说,我认为这是参数过去是实际值而不是空值时的遗留问题。。。例如,它们过去是
和(@Param1=''或(@Param1''和[Field1]=@Param1))
。由于SQL不像C#
&
或VB.NET
和ALSO
那样做短路,我认为这是必要的。