【问题标题】:Extract attribute from XML in SQL Server从 SQL Server 中的 XML 中提取属性
【发布时间】:2017-06-28 20:10:45
【问题描述】:

鉴于此 XML:

DECLARE @input XML = '<Data>
  <Tab Name="UserData">
    <Row>
      <BeneficialOwnerName>Fred Flintstone</BeneficialOwnerName>
      <TaxID>111-11-1111</TaxID>
    </Row>
    <Row>
      <BeneficialOwnerName>Barney Rubble</BeneficialOwnerName>
      <TaxID>222-22-2222</TaxID>
    </Row>
  </Tab>
  <Tab Name="OtherData">
    <Row>
      <BeneficialOwnerName>Bugs Bunny</BeneficialOwnerName>
      <TaxID>333-33-3333</TaxID>
    </Row>
    <Row>
      <BeneficialOwnerName>Road Runner</BeneficialOwnerName>
      <TaxID>444-44-4444</TaxID>
    </Row>
  </Tab>  
</Data>'

我想退货:

Name     BeneficialOwnerName    TaxID
UserData  Fred Flintstone       111-11-1111
UserData  Barney Rubble         222-22-2222
OtherData Bugs Bunny            333-33-3333
OtherData Road Runner           444-44-4444

我的 SQL 如下所示:

SELECT
  Name = XCol.value('@Name','varchar(25)'),   
  BeneficialOwnerName = XCol.value('BeneficialOwnerName[1]','varchar(25)'),
  TaxID = XCol.value('TaxID[1]','varchar(25)')
FROM 
  @input.nodes('/Data/Tab/Row') AS XTbl(XCol)

但是根据我如何调整 FROM 子句,我会得到两行选项卡名称或 4 行选项卡名称为 Null 的数据

我需要做什么才能显示数据?

谢谢

卡尔

【问题讨论】:

  • 这是一个好问题:copy-n_paste 测试代码,预期输出,自己的努力... +1 从我这边

标签: sql-server xml


【解决方案1】:

从性能的角度来看,访问父元素往往比单独选择每个级别更昂贵。对于您的示例,下面的代码稍微快一些,但会在更大的 XML 上产生显着差异:

SELECT
  Name = t.c.value('@Name','varchar(25)'),   
  BeneficialOwnerName = r.c.value('BeneficialOwnerName[1]','varchar(25)'),
  TaxID = r.c.value('TaxID[1]','varchar(25)')
FROM @input.nodes('/Data/Tab') t(c)
    cross apply t.c.nodes('./Row') r(c);

【讨论】:

  • 好答案,我这边 +1,只是一个小小的提示:如果你想要最好的性能,最好使用 (TaxID/text())[1] 或者 - 甚至稍微快一点 - TaxID[1]/text()[1]。您可能会read this answer 为什么使用text() 更快。
  • @Shnugo,从技术上讲是的,两者之间是有区别的。然而,即使计划不同,这个样本的性能差异也可以忽略不计。需要更大或更复杂的 XML 才能注意到这一点。
【解决方案2】:

一切都很好,除了名称列。试试这个:

SELECT
  Name = XCol.value('../@Name','varchar(25)'),   
  BeneficialOwnerName = XCol.value('BeneficialOwnerName[1]','varchar(25)'),
  TaxID = XCol.value('TaxID[1]','varchar(25)')
FROM 
  @input.nodes('/Data/Tab/Row') AS XTbl(XCol)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 2021-12-23
    • 1970-01-01
    相关资源
    最近更新 更多