【问题标题】:Convert XML column to Table Data in MS SQL Query.在 MS SQL Query 中将 XML 列转换为表数据。
【发布时间】:2014-07-04 00:59:15
【问题描述】:

在我的数据库中的一个表中,我有一列,其中整个条目是一个长 XML 字符串,其结构如下:

  <Group1>
      <Title>
          <Name>John Doe</Name>
          <Phone>555-3421</Phone>
          <Email>catman@gmail.com</Email>
          (+more)
      </Title>
  </Group1>

这是我的 SELECT 语句,它的输出如下:

SELECT TheKey, TheData FROM MyTable;

SQL Server Management Studio 中的输出:

TheKey  TheData
10000   <Group1><Title><Name>John Doe</Name><Phone>893-3421</Phone><Email>catman@gmail.com</Email></Title></Group1>
10001   <Group1><Title><Name>Mary Sue</Name><Phone>381-2342</Phone><Email>thebestdude@gmail.com</Email></Title></Group1>
10002   <Group1><Title><Name>Mark Dark</Name><Phone>312-7626</Phone><Email>mybook231@gmail.com</Email></Title></Group1>
10003   <Group1><Title><Name>Garth Dan</Name><Phone>341-4572</Phone><Email>lampshade032@gmail.com</Email><State>California</State></Title></Group1>

我想编写某种 MS SQL 查询,它将这样的数据返回给我:

TheKey  Name        Phone       Email                          State
10000   John Doe    893-3421    catman@gmail.com                NULL
10001   Mary Sue    381-2342    thebestdude@gmail.com           NULL
10002   Mark Dark   312-7626    mybook231@gmail.com             NULL
10003   Garth Dan   341-4572    lampshade032@gmail.com         California

注意最后一个条目有一个额外的 XML 标记 &lt;State&gt;,而其他条目没有。我希望它像这样灵活 - 使用某种父/子引用?

我们将不胜感激任何帮助,我似乎在任何地方都找不到类似的东西 =)

【问题讨论】:

  • 这是一个很好的问题。不幸的是,有人决定将这种格式的信息转储到 sql 表的一列中。但它也发生在我身上!

标签: sql xml


【解决方案1】:

如果您的 XML 列存储为 XML 类型,那么您可以使用 XPath 查询来获取每一列。像这样:

SELECT TheKey, 
    TheData.value('(/Group1/Title/Name)[1]', 'varchar(100)') AS Name,
    TheData.value('(/Group1/Title/Phone)[1]', 'varchar(100)') AS Phone,
    TheData.value('(/Group1/Title/Email)[1]', 'varchar(250)') AS Email,
    TheData.value('(/Group1/Title/State)[1]', 'varchar(100)') AS [State]
FROM MyTable

如果列 MyData 是 varchar 而不是 XML,那么您可以在查询期间强制转换它。像这样:

SELECT TheKey, 
    Cast(TheData AS XML).value('(/Group1/Title/Name)[1]', 'varchar(100)') AS Name,
    Cast(TheData AS XML).value('(/Group1/Title/Phone)[1]', 'varchar(100)') AS Phone,
    Cast(TheData AS XML).value('(/Group1/Title/Email)[1]', 'varchar(250)') AS Email,
    Cast(TheData AS XML).value('(/Group1/Title/State)[1]', 'varchar(100)') AS [State]
FROM MyTable

顺便说一句,我从另一篇 SO 文章中获得了这些信息。 (投票让其他人更容易找到它)How to query xml column in tsql

【讨论】:

  • 谢谢。我认为这会很好。但是,是否可以使其动态化,例如,不必写出(/Group1/Title/Name)或 AS 名称、AS 电话、AS 电子邮件等。像,有没有办法说“输出孩子这个父母并为每个人制作列”?或者是在 SQL Query 语句中不可能的事情。 (我现在戴着网络开发者的帽子)。
  • 这可能是可能的,但我从来没有做过,也没有见过。您可以尝试发布另一个关于此的 SO 问题。
【解决方案2】:
--OBTAIN THE XML DATA
     declare @xml as xml = '
     <division>
      <linea>
        <id_division>01</id_division>
        <division>REPUESTOS</division>
      </linea>
      <linea>
        <id_division>02</id_division>
        <division>BATERIAS</division>
      </linea>
      <linea>
        <id_division>03</id_division>
        <division>LUBRICANTES</division>
      </linea>
      <linea>
        <id_division>04</id_division>
        <division>NEUMATICOS</division>
      </linea>
    </division>'
-- create table or you can use existing table for structure
            create table #tmp_table (
                                    id_division integer,
                                    division nvarchar(20)
                                    )

            declare @docHandle int
            EXEC sp_xml_preparedocument @docHandle OUTPUT, @xml;  

            SELECT *
                FROM OPENXML(@docHandle, '/division/linea',3)   
                WITH #tmp_table;  

            ---DELETE tmp_TABLE
            drop table #tmp_table

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多