XML到SQL Server的解析问题

时间:2018-07-04 13:55:08

标签: sql sql-server xml

我正在XML下方进行解析,并尝试获取节点的所有属性/值。

declare @XBL xml='
<Root>
      <Department>
             <Employees>
                <Employee type="temp">
                 Jason
                </Employee>
                <Employee type="perm">
                 Roy
                </Employee>
             </Employees>
      </Department>
      <Department>
             <Employees >
                <Employee type="temp2">
                 Kevin
                </Employee>
             </Employees>
      </Department>
</Root>'

SELECT  
    [Type] = XC.value('(@type)[1]', 'varchar(25)'),
       [Name] = XC.value('(../Employee)[1]' , 'varchar(30)')
FROM
    @XBL.nodes('Root/Department/Employees/Employee') AS XTbl(XC)

上述查询的输出为我提供了所有属性,但只有第一个值(Jason)。

Type  Name 
temp  Jason
perm  Jason
temp2 Kevin 

预期输出:

Type  Name 
temp  Jason
perm  Roy
temp2 Kevin

2 个答案:

答案 0 :(得分:2)

这应该是您所追求的:

SELECT XBL.E.value('@type','varchar(25)') AS [Type],
       XBL.E.value('(./text())[1]','varchar(30)') AS [Name]
FROM @XBL.nodes('Root/Department/Employees/Employee') XBL(E);

还要注意使用/text()。从节点内部返回数据时,添加/text()实际上可以提高查询的性能。

编辑:另外,根据您的示例x​​ml,为[Name]返回的值实际上将为'{Line break} Jason{Line break}'(显然用实际字符替换了换行符)。是您想要的,还是要删除空格和换行符/回车符?

答案 1 :(得分:1)

您正在选择上级部门的第一个Employee子级:

[Name] = XC.value('(../Employee)[1]' , 'varchar(30)'
                   ^^^^^^^^^^^^^^^^

要选择当前雇员,请使用:

[Name] = XC.value('(.)[1]' , 'varchar(30)')
                   ^^^^^^

Example at SQL Fiddle.