替代WHERE子句中的SET ANSI_NULLS OFF

时间:2017-01-25 12:50:21

标签: sql sql-server

我有一个SP,它有一个非常复杂的SQL语句,我需要能够将某些列与NULL进行比较,例如。

...
FROM Categories
WHERE PID = @parentID

@parentID是一个SP参数,可以有效为NULL PID(父ID)是uniqueidentifier,也可以是有效的NULL(顶级类别)。 我可以使用SET ANSI_NULLS OFF,但documentation说:

  

在SQL Server的未来版本中,ANSI_NULLS将始终为ON和   任何明确将选项设置为OFF的应用程序都将生成   一个错误。避免在新的开发工作和计划​​中使用此功能   修改当前使用此功能的应用程序。

IS NULL的情况下(以及不使用动态SQL),有什么可以是优雅的方式,而不是使用@parentID=NULL重复相同的查询:

IF @parentID IS NULL 
  SELECT...WHERE PID IS NULL
ELSE
  SELECT...WHERE PID = @parentID

编辑:我想避免使用IF,因为我讨厌重复(巨大的)代码。

3 个答案:

答案 0 :(得分:5)

类似的东西:

select ..
FROM Categories
WHERE PID = @parentID or (PID is null and @parentID is null)

答案 1 :(得分:4)

我认为if版本是最清晰的。但是,多个查询的一个大问题是存储过程在首次运行时编译代码 - 它可能会对执行计划做出错误的决定。

一个选项是包含recompile

另一种方法是组合查询,但是每个部分应该有效地使用索引:

select c.* from categories c where pid is null and @parentid is null
union all
select c.* from categories c where pid = @parentId;

这比if版本的效率稍微低一点。

答案 2 :(得分:0)

这是一种简洁简洁的代码:

SELECT *
FROM Categories
WHERE COALESCE(PID, 'NULL-MATCH') = COALESCE(@parentID, 'NULL-MATCH')