在SQL 2005和SQL 2012上使用ELEMENTS XSINIL时的不同行为

时间:2014-03-17 06:53:26

标签: sql sql-server xml

我在SQL 2005(9.0.5057)和SQL 2012(11.0.3128)之间存在遗留问题。当我在SQL 2005和SQL 2012上运行以下示例SQL查询时,我得到不同的结果:

select
  0 'test1/@old', null 'test1',
  null 'test2/@old', 2 'test2',
  2 'test3/@old', 2 'test3',
  null 'test4/@old', null 'test4'
FOR XML PATH('Data'), ELEMENTS XSINIL

对于SQL 2005,结果是:

<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <test1 old="0" />
  <test2>2</test2>
  <test3 old="2">2</test3>
  <test4 xsi:nil="true" />
</Data>

对于SQL 2012,结果是:

<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <test1 old="0" xsi:nil="true" />
  <test2>2</test2>
  <test3 old="2">2</test3>
  <test4 xsi:nil="true" />
</Data>

Test1是问题发生的地方。 SQL 2012的行为是正确的,但我很难在SQL 2005中找到补丁或解决此问题。

我在SQL Server 2008 R2(10.50.2500)上运行了相同的测试,但获得了SQL 2005结果。

我错过了什么地方吗?

1 个答案:

答案 0 :(得分:4)

  

我错过了什么地方吗?

不,这似乎是在SQL Server 2012中修复的SQL Server中的错误,可能在SP1中。

SQLXML: for xml path(), elements xsinil: xsi:nil="true" attribute is missing when other attribute is generated on the same element

  

我正在努力寻找补丁或在SQL中解决这个问题   2005。

您可以接受的解决方法是将缺少的属性添加到应有的位置。

将查询结果存储在XML变量中,然后使用modify() Method (xml Data Type)insert (XML DML)

一次只能添加一个值,因此必须使用exist() Method (xml Data Type)在循环中完成,以检查缺少xsi:nil属性的空节点。

declare @X xml

set @X = (
         select
           0 'test1/@old', null 'test1',
           null 'test2/@old', 2 'test2',
           2 'test3/@old', 2 'test3',
           null 'test4/@old', null 'test4'
         for xml path('Data'), elements xsinil
         )

while @X.exist('//*[empty(text()) and empty(*) and empty(@xsi:nil)]') = 1
  set @X.modify('declare namespace xsi="http://www.w3.org/2001/XMLSchema-instance";
                 insert (attribute xsi:nil {"true"}) into 
                   (//*[empty(text()) and empty(*) and empty(@xsi:nil)])[1]')

select @X

//*为您提供XML中的所有节点 括号[]用于谓词 empty(text())检查节点中的文本 empty(*)检查子节点 empty(@xsi:nil)搜索xsi:nil属性的存在。