【问题标题】:SQL Server: ISNULL on uniqueidentifierSQL Server:唯一标识符上的 ISNULL
【发布时间】:2015-11-23 16:51:17
【问题描述】:

我试图在WHERE 子句中比较列col1 和变量@myvar。两者通常都包含 GUID,但也可能具有 NULL 值。 我想我可以通过使用WHERE ISNULL(col1, '')=ISNULL(@myvar, '') 来解决NULL=NULL 评估为FALSE 的事实。这将改为比较两个空字符串,并评估为 TRUE。

但是,这将产生以下错误消息:

消息 8169,级别 16,状态 2,行 3 转换时转换失败 从字符串到唯一标识符。

我试过了

DECLARE @myvar uniqueidentifier = NULL
SELECT ISNULL(@myvar,'') as col1

同样的错误信息。

两个问题: 首先,我正在尝试将 uniqueidentifier 变量(即使它具有 NULL 值)转换为(空!)字符串,而不是相反,如错误消息所示。是什么赋予了?

其次,有没有更好的方法来表达我需要的 WHERE 子句,以允许比较可能为 NULL 的唯一标识符?

【问题讨论】:

  • 您是否也希望将有效的唯一标识符也转换为字符串?
  • shawnt00,对于 WHERE 子句,非 NULL 唯一标识符不需要转换为字符串。比较它们只需要评估为 TRUE,所以我只检索它们相等的记录。

标签: sql sql-server null uniqueidentifier isnull


【解决方案1】:

我认为下面的表达式可以用来检查 GUID 列是否为空

CAST(0x0 AS UNIQUEIDENTIFIER)

类似的东西

...WHERE GuidId <>  CAST(0x0 AS UNIQUEIDENTIFIER)

【讨论】:

    【解决方案2】:

    由于您传递的第一个参数isnull 不是文字null,它将确定该调用的返回类型,在您的情况下为uniqueidentifier。第二个参数 '' 不能转换为这种类型,因此会出现错误。

    解决这个问题的一种方法是明确检查nulls:

    WHERE (@myvar IS NULL AND col1 IS NULL) OR (col1 = @myvar)
    

    【讨论】:

    • 还有第二部分需要牢记。在将列放入函数(如 ISNULL)的那一刻,您使查询优化器无法发挥其潜力。看看这个(“sargable”):stackoverflow.com/q/799584/5089204
    • Shnugo,我什至没有考虑过这个。这可能会产生重要的影响,因为所有这些都将成为 Python 程序的一部分,该程序将连续数千次(通过 pyodbc)运行此查询(或非常相似的查询),因此可以节省任何时间他们太小了!
    • @Shnugo,经过进一步研究,我是否认为这适用于用户定义的函数以及内置函数......?
    • @ThorstenVogt,是的,最大的性能问题是让优化器完成它的工作。不可分割的部分会使查询变得非常缓慢,但你无法想象为什么......
    【解决方案3】:

    ISNULL 不适合您的原因是替换值(如果检查表达式确实为空,则使用的值)必须隐式转换为检查表达式的类型。

    您的WHERE 子句可以使用col IS NULL AND @var IS NULL 来检查该状态。

    【讨论】:

      【解决方案4】:

      正如其他人指出的那样,从结果中排除 NULL 值,然后进行比较。您可以使用 COALESCE 从比较中排除 NULL 值。

      【讨论】:

      • 看看我在@Mureinik下面的评论。避免“sargability”的函数调用(COALESCE)
      • 最好是一个示例,展示如何将不可分割的 where 子句转换为可分割的 select 语句,两者都使用 COALESCE 或 ISNULL 来解决问题。
      • COALESCE 将解决我得到很好的错误的问题。不过,我将获得额外的潜在绩效奖金。 :o) 我只需要 WHERE 子句,而不是 SELECT 语句。
      • @EmacsUser,如果您点击我在 Mureinik 答案下方的评论中发布的链接,您会发现很多示例。
      • @TVogt,也许我没有正确理解你,但希望 WHERE 中的某些内容不会影响查询本身是错误的。恰恰相反!想象一下,您的“WHERE”将包含数百万行的表过滤到几行。这应该是第一步。如果优化器无法“查看”它,则在选择 之后应用此过滤器。数百万行被提取 - 并在最后被丢弃......
      【解决方案5】:

      试试下面的代码:

      WHERE ISNULL([Guid], NEWID()) = @myvar 
      

      【讨论】:

      • 欢迎来到 Stack Overflow!虽然欢迎使用此代码 sn-p,并且可能会提供一些帮助,但它将是 greatly improved if it included an explanation如何为什么 这可以解决问题。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人!请edit您的答案添加解释,并说明适用的限制和假设。
      • 这仍然存在将两个空值视为不相等的问题,因为 NEWID() 返回的是随机 GUID,而不是空白 GUID。
      【解决方案6】:

      这是解决此问题的另一种方法:

      DECLARE @myvar uniqueidentifier = NEWID()
      
      SELECT * FROM TABLE
      Where ISNULL(col1,@myvar) = ISNULL(Col2,@myvar)
      

      这将解决您的错误。从字符串转换为uniqueidentifier时转换失败。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多