使用SQL Server中的XML列从表中提取数据

时间:2016-04-27 16:41:14

标签: sql-server xml tsql xpath xquery

我将下面的示例XML保存在一个名为CE_ExtendedElements的表中,名为xmlValue的列

<SIF_ExtendedElements xmlns="">
  <SIF_ExtendedElement Name="EmergencyNumber">00000000</SIF_ExtendedElement>
  <SIF_ExtendedElement Name="EmergencyNumber">00000000</SIF_ExtendedElement>
  <SIF_ExtendedElement Name="Qualifications">
  <Qualification>
    <Qualification>Bsc</Qualification>
    <QualificationWhenHired>True</QualificationWhenHired>
    <Major>Compuetr</Major>
    <GraduationYear>1993</GraduationYear>
    <Institution>Home Univ</Institution>
    <CountryID>1234</CountryID>
  </Qualification>
  <Qualification>
    <Qualification>Bsc</Qualification>
    <QualificationWhenHired>True</QualificationWhenHired>
    <Major>Compuetr</Major>
    <GraduationYear>1993</GraduationYear>
    <Institution>Home Univ</Institution>
    <CountryID>1234</CountryID>
  </Qualification>
</SIF_ExtendedElement>
  <SIF_ExtendedElement Name="JoinDate">2003-09-15T00:00:00</SIF_ExtendedElement>
</SIF_ExtendedElements>

任何项目的最大节点数仅为2(用户可以为每条记录添加2个EmergencyNumber和2个Qualifications)。

有人可以帮我阅读上面的XML,使用SQL语句将XML节点转换为列吗?与下表相同:

EmergencyNumber1 | EmergencyNumber2 |资格1 | QualificationWhenHired1 | Major1 | ..... |资格2 | QualificationWhenHired2 | Major2 | .....

由于

2 个答案:

答案 0 :(得分:1)

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)


SELECT @XML = XMLvalue FROM CE_ExtendedElements


EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML


SELECT EmergencyNumber1, EmergencyNumber2, Qualification, QualificationWhenHired, Major, Institution, CountryID
FROM OPENXML(@hDoc, 'SIF_ExtendedElements/Qualifications/Qualification')
WITH 
(
  EmergencyNumber1 [varchar](50) '../../@EmergencyNumber1',
  EmergencyNumber2 [varchar](50) '../../@EmergencyNumber2',
  Qualification [varchar](100) '@Qualification',
  QualificationWhenHired [varchar](50) '@QualificationWhenHired',
  Major [varchar](50) '@Major',
  Institution [varchar](50) '@Institution',
  CountryID [varchar](50) '@CountryID'
)


EXEC sp_xml_removedocument @hDoc
GO

这应该非常接近!

答案 1 :(得分:0)

我必须说,XML的结构似乎不是最好的......

但你可以这样试试:

注意,使用虚拟命名空间并更改数据以便更好地控制

DECLARE @xml XML=
'<SIF_ExtendedElements xmlns="http://dummy_uri">
  <SIF_ExtendedElement Name="EmergencyNumber">11111111</SIF_ExtendedElement>
  <SIF_ExtendedElement Name="EmergencyNumber">22222222</SIF_ExtendedElement>
  <SIF_ExtendedElement Name="Qualifications">
    <Qualification>
      <Qualification>Bsc1</Qualification>
      <QualificationWhenHired>True</QualificationWhenHired>
      <Major>Compuetr</Major>
      <GraduationYear>1991</GraduationYear>
      <Institution>Home Univ</Institution>
      <CountryID>1111</CountryID>
    </Qualification>
    <Qualification>
      <Qualification>Bsc2</Qualification>
      <QualificationWhenHired>True</QualificationWhenHired>
      <Major>Compuetr</Major>
      <GraduationYear>1992</GraduationYear>
      <Institution>Home Univ</Institution>
      <CountryID>2222</CountryID>
    </Qualification>
  </SIF_ExtendedElement>
  <SIF_ExtendedElement Name="JoinDate">2003-09-15T00:00:00</SIF_ExtendedElement>
</SIF_ExtendedElements>';

WITH XMLNAMESPACES(DEFAULT 'http://dummy_uri')
SELECT Elmt.value('(SIF_ExtendedElement[@Name="EmergencyNumber"])[1]','varchar(max)') AS EmergencyNumber1
      ,Elmt.value('(SIF_ExtendedElement[@Name="EmergencyNumber"])[2]','varchar(max)') AS EmergencyNumber2
      ,Qlfct.value('Qualification[1]/Qualification[1]','varchar(max)') AS Qualification1 
      ,Qlfct.value('Qualification[1]/QualificationWhenHired[1]','bit') AS QualificationWhenHired1 
      ,Qlfct.value('Qualification[1]/Major[1]','varchar(max)') AS Major1 
      ,Qlfct.value('Qualification[1]/GraduationYear[1]','int') AS GraduationYear1 
      ,Qlfct.value('Qualification[1]/Institution[1]','varchar(max)') AS Institution1 
      ,Qlfct.value('Qualification[1]/CountryID[1]','int') AS CountryID1 
      ,Qlfct.value('Qualification[2]/Qualification[1]','varchar(max)') AS Qualification2
      ,Qlfct.value('Qualification[2]/QualificationWhenHired[1]','bit') AS QualificationWhenHired2 
      ,Qlfct.value('Qualification[2]/Major[1]','varchar(max)') AS Major2
      ,Qlfct.value('Qualification[2]/GraduationYear[1]','int') AS GraduationYear2
      ,Qlfct.value('Qualification[2]/Institution[1]','varchar(max)') AS Institution2 
      ,Qlfct.value('Qualification[2]/CountryID[1]','int') AS CountryID2 
FROM @xml.nodes('/SIF_ExtendedElements') AS A(Elmt)
CROSS APPLY Elmt.nodes('SIF_ExtendedElement[@Name="Qualifications"]') AS B(Qlfct)