如何仅使用Xpath从SQL Server中的空XML标记返回null?


8

我有一个应用程序,可以在XML列中存储有关记录的各种用户定义的数据点。我无法控制如何存储或更新这些内容。

当我查询列时,它可以返回3个值中的1个:

  1. 价值
  2. 空值
  3. 空字符串

$ 64问题我想使用xpath将这些空字符串作为null返回。

我已经找到了很多有关将null作为空字符串返回的答案,但这种方式一无所获。

当有人删除了值时,它们最终以这种方式结束,而不是删除标签,而是将其空白为<value />标签。当从未设置过该值时,将出现空值。他们没有包括xsi:nil。

我已经完成了一个案例声明:

    select
    so.SalesOrderId,
    Case
        when sopc.value('(Value)[1]','smalldatetime') IS null then Null
        when sopc.value('(Value)[1]','smalldatetime') ='' then Null
        Else sopc.value('(Value)[1]','smalldatetime')
    End as sopc
    From
    SalesOrders so
    Outer apply so.CustomColumns.nodes('/CustomColumnsCollection/CustomColumn[Name="ProjCompleted"]') sopc(sopc)

但这感觉效率低下,并且这不是唯一的专栏,因此使代码更长且更难维护。

编辑以包括样本数据

SalesOrderId    CustomColumns
SO 1            "<CustomColumnsCollection>
                   <CustomColumn>
                     <Name>ProjCompleted</Name>
                     <DataType>1</DataType>
                     <Value />
                   </CustomColumn>
                 </CustomColumnsCollection>"
SO 2           "<CustomColumnsCollection>
                  <CustomColumn>
                     <Name>ProjCompleted</Name>
                     <DataType>1</DataType>
                     <Value>'2017-11-21'</Value>
                  </CustomColumn>
                </CustomColumnsCollection>"
SO 3           "<CustomColumnsCollection>
                </CustomColumnsCollection>"

**Output**
Current      Desired
''           null
2017-11-21   2017-11-21
null         null

提前致谢。


谢谢Scott-正如您所看到的,这是我的第一个问题,有没有首选的格式?
TimNewman '17

只需使用包含XML示例并包含另一个预期结果的代码块的代码块(类似于您已经发布的代码)来更新您的问题。请参阅如何创建最小,完整和可验证的示例
Scott Hodgin

谢谢-我已经接受了答案,但我仍将编辑问题,以使其对发现此问题的其他任何人有用。
TimNewman '17

Answers:


11

指定元素text()内的节点Value。当您有一个空标签时,该节点丢失。

尝试这个:

declare @X xml;
set @X = '<Value/>';

select @X.value('(Value/text())[1]', 'smalldatetime'),
       @X.value('(Value/text())[1]', 'varchar(max)'),
       @X.value('(Value/text())[1]', 'int'),
       @X.value('(Value)[1]', 'smalldatetime'),
       @X.value('(Value)[1]', 'varchar(max)'),
       @X.value('(Value)[1]', 'int');

结果:

------------------- ---------- ----------- ----------------------- ---------- -----------
NULL                NULL       NULL        1900-01-01 00:00:00                0

通常,总是指定text()节点是一件好事。查询计划更简单,更高效。

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.