2

因为我们有两个选项来拦截来自数据库的空值......

  1. 一片空白
  2. 合并

以下是为上述两个函数编写查询的方法...

Select IsNull(Columnname, '') As validColumnValue From TableName

Select Coleasce(Columnname, '') As validColumnValue From TableName

查询 - 在哪种情况下应该首选哪个,为什么?

4

3 回答 3

5

这已被散列并重新散列。除了我在评论中指出的提示以及上面发布的链接和解释@xQbert 之外,根据请求,这里是使用子查询对 COALESCE 与 ISNULL 的解释。让我们考虑这两个查询,它们的结果是相同的:

SELECT COALESCE((SELECT TOP (1) name FROM sys.objects), N'foo');

SELECT ISNULL((SELECT TOP (1) name FROM sys.objects), N'foo');

(关于使用没有 ORDER BY 的 TOP 到 /dev/null/ 的评论,谢谢。)

在 COALESCE 案例中,逻辑实际上被扩展为如下内容:

SELECT CASE WHEN (SELECT TOP (1) ...) IS NULL
    THEN (SELECT TOP (1) ...)
    ELSE N'foo'
END

使用 ISNULL,这不会发生。有一个内部优化似乎可以确保子查询只被评估一次。我不知道微软以外的任何人是否知道这种优化是如何工作的,但如果你比较计划,你就可以做到这一点。这是 COALESCE 版本的计划:

在此处输入图像描述

这是 ISNULL 版本的计划 - 注意它是多么简单(并且扫描只发生一次):

在此处输入图像描述

在 COALESCE 情况下,扫描发生两次。这意味着子查询被评估两次,即使它没有产生任何结果。如果您添加 WHERE 子句以使子查询产生 0 行,您将看到类似的差异 - 计划形状可能会更改,但您仍会看到双重查找 + 查找或扫描 COALESCE 案例。这是一个稍微不同的例子:

SELECT COALESCE((SELECT TOP (1) name FROM sys.objects 
    WHERE name = N'no way this exists'), N'foo');

SELECT ISNULL((SELECT TOP (1) name FROM sys.objects 
    WHERE name = N'no way this exists'), N'foo');

这次 COALESCE 版本的计划 - 你可以再次看到代表子查询的整个分支逐字重复:

在此处输入图像描述

还有一个更简单的计划,使用 ISNULL 完成大约一半的工作:

在此处输入图像描述

您还可以在 dba.se 上查看此问题以进行更多讨论:

我的建议是这样的(您可以在提示和上述问题中看到我的原因):信任但验证。我总是使用 COALESCE (因为它是 ANSI 标准,支持两个以上的参数,并且不会像数据类型优先级那样做很奇怪的事情),除非我知道我使用子查询作为表达式之一(我不记得曾经做过这样的理论工作之外的工作),或者我遇到了一个真正的性能问题,只是想比较一下 COALESCE 与 ISNULL 是否有任何实质性的性能差异(在子查询案例之外,我还没有找到)。由于我几乎总是将 COALESCE 与类似数据类型的参数一起使用,因此除了回顾我过去所说的内容外,我很少需要进行任何测试(我也是xQbert 7 年前指出的 aspfaq 文章)。

于 2012-05-19T23:42:39.567 回答
1

开始幽默:第一个,第二个永远不会工作它拼写错误:D END幽默

---清理响应---

isNull(value1,value2) 的特点

  • 仅支持 1 次评估,如果第一个为 null,则使用第二个,因此如果它也为 null,则返回 null!
  • 是非ANSI标准。这意味着如果数据库可移植性是一个问题,请不要使用这个
  • isnull(value1,value2) 将返回 Value1 的数据类型
  • 将返回所选值的数据类型,并在无法进行隐式转换时失败

Coalesce 的特点(Value1, Value2, value3, value...)

  • 支持Null的多重估值;基本上会从列表中拉入第一个非空值。如果列表中的所有值都为 null,则返回 null。
  • 是 ANSI 标准,这意味着数据库可移植性不应该成为问题。
  • 将返回所选值的数据类型,如果选择中的所有字段不返回相同的数据类型,则会失败。

所以直接回答这个问题:是否需要开发SQL取决于情况

  • 独立于数据库;合并使用更正确。
  • 允许多重评估;coalesce 更正确(当然你可以一遍又一遍地嵌入 isnull ......)但是把它放在性能显微镜下,coalesce 可能会赢。(我没有测试过)
  • 您是否使用支持 isNull 的数据库引擎?(如果不使用合并)
  • 你想如何处理类型转换?隐含与否。

---ORIGINAL----- 为 null 仅支持 2 次评估

coalesce 支持更多... coalesce (columnName1, ColumnName2, ColumnName3, '')

coalesce 返回类似于案例评估的数据类型,而 isnull 返回列表中第一个的数据类型。(我觉得很有趣!)

至于什么时候用哪个。您必须通过查看 SQL 2008 和 2005 上的执行计划进行调查,不同的版本不同的引擎不同的执行方式。

此外,coalesce 是 ansii 标准,isnull 是特定于引擎的。因此,如果您希望在 dbengine 之间具有更大的可移植性,请使用 coalesce。

更多信息在这里 aspfaq这里 msdn 博客

于 2012-05-19T19:19:25.627 回答
0

你可以考虑到这一点。

  1. ISNULL函数需要两个参数:要检查的值和空值的替换

    2. COALESCE函数的工作方式略有不同COALESCE将采用任意数量的参数并返回第一个非NULL值,我更喜欢COALESCE 而不是ISNULL,因为符合ANSI标准,而ISNULL不符合。

    我希望你找到了你的问题的答案。

于 2012-05-20T00:09:40.933 回答