【问题标题】:Challenge - Processing XML into T-SQL table structure?挑战 - 将 XML 处理成 T-SQL 表结构?
【发布时间】:2010-07-06 16:29:47
【问题描述】:

如果你有这个 XML:

<people>
  <person id="1">
    <firstname>John</firstname>
    <surname>Doe</surname>
  </person>
  <person id="2">
    <firstname>Mary</firstname>
    <surname>Jane</surname>
  </person>
</people>

而你想要这张桌子:

id  firstname  surname
--- ---------- ----------
1   John       Doe
2   Mary       Jane

如何使用 T-SQLXML 获得它?

再添一把扳手:假设您知道&lt;person&gt;&lt;firstname&gt;&lt;surname&gt; 元素的深度,但您不知道它们叫什么!

如果您认为将其发布到 reddit 更好,请随意火焰 :)

【问题讨论】:

    标签: xml tsql


    【解决方案1】:

    我建议使用 XQuery 接口,而不是相当笨重的旧 OPENXML 方法:

    SELECT
        Ppl.Person.value('(@id)[1]', 'int') AS 'ID',
        Ppl.Person.value('(firstname)[1]', 'varchar(20)') AS 'First Name',
        Ppl.Person.value('(surname)[1]', 'varchar(20)') AS 'Last Name'
    FROM
        @input.nodes('/people/person') as Ppl(Person)
    

    这是在 SQL Server 2005 及更高版本中执行此操作的首选方式。

    输出是一样的:

    ID  First Name  Last Name
    1    John             Doe
    2    Mary             Jane
    

    但是,如果您不了解 XML 结构,则无法真正做到这一点.....

    【讨论】:

    • OPENXML,虽然笨重,但可以快很多 (social.msdn.microsoft.com/Forums/en-US/sqlxml/thread/…)。因此,即使它可能不是“首选方式”,但有时性能胜过偏好。但我仍然赞成你的答案,因为我认为这是一个很好的答案:)。
    • 我喜欢这两个答案,但tbh,这个更简单(阅读:代码更少,所以我理解得更好,哎呀,我只是用鼠标敲击我的头,duh :) 所以这是我的'正确答案',但他们都很棒。第一个需要我学习更多才能理解(我不反对,仅供参考)
    • 我发现使用 XQUERY 和 SELECT/INTO 转储到临时表,然后使用 INSERT/INTO 从临时表到生产表要快得多。
    【解决方案2】:

    这将为您提供桌子。如果您不知道 XML 列名,那么您可能必须使用动态 SQL(例如,对于“firstname varchar(20) 'firstname'”,您必须将 'firstname' 替换为 XML 列名,我假设你会在运行时确定):

    DECLARE @idoc int
    DECLARE @doc varchar(1000)
    SET @doc ='
    <people>
      <person id="1">
        <firstname>John</firstname>
        <surname>Doe</surname>
      </person>
      <person id="2">
        <firstname>Mary</firstname>
        <surname>Jane</surname>
      </person>
    </people>
    '
    /* Create an internal representation of the XML document */
    EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
    -- Execute a SELECT statement that uses the OPENXML rowset provider.
    SELECT    *
    FROM       OPENXML (@idoc, '/people/person',1)
                WITH (id varchar(20),
                      firstname varchar(20) 'firstname',
                      surname varchar(20) 'surname')
    EXECUTE sp_xml_removedocument @idoc
    

    结果:

    id  firstname       surname
    1   John            Doe
    2   Mary            Jane
    

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 2017-06-23
      • 2012-04-24
      • 2019-08-11
      • 1970-01-01
      • 2021-07-03
      • 2011-01-25
      相关资源
      最近更新 更多