【问题标题】:SQL Server generating XML with generic field elementsSQL Server 使用通用字段元素生成 XML
【发布时间】:2014-08-20 18:58:51
【问题描述】:

我基本上是在试图扭转这个问题的要求...... SQL Server query xml attribute for an element value

我需要生成一个“行”元素的结果集,其中包含一组“字段”元素,其属性定义了键。

<resultset statement="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
    <field name="id">1</field>
    <field name="version”>0</field>
    <field name="property">My Movie</field>
    <field name="release_date">2012-01-01</field>
    <field name="territory_code”>FR</field>
    <field name="territory_description">FRANCE</field>
    <field name="currency_code”>EUR</field>
</row>
<row>
    <field name="id">2</field>
    <field name="version”>0</field>
    <field name="property">My Sequel</field>
    <field name="release_date">2014-03-01</field>
    <field name="territory_code”>UK</field>
    <field name="territory_description">United Kingdom</field>
    <field name="currency_code”>GBP</field>
</row>
</resultset>

我有一个返回这个的查询...

<resultset statement="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
    <id>1</id>
    <version>0</version>
    <property>My Movie</property>
    <release_date>2012-01-01</release_date>
    <territory_code>FR</territory_code>
    <territory_description>FRANCE</territory_description>
    <currency_code>EUR</currency_code>
</row>
<row>
    <id>2</id>
    <version>0</version>
    <property>My Sequel</property>
    <release_date>2014-03-01</release_date>
    <territory_code>UK</territory_code>
    <territory_description>UNITED KINGDOM</territory_description>
    <currency_code>GBP</currency_code>
</row>
</resultset>

在我的 SQL 语句中使用 FOR XML PATH ('row'), ROOT ('resultset')

我错过了什么?谢谢。

【问题讨论】:

    标签: sql sql-server xml


    【解决方案1】:

    这在 SQL Server 中有点涉及 - 正常行为就是您所看到的 - 列名将用作 XML 元素名。

    如果您真的希望所有 XML 元素的名称相同,则必须使用如下代码:

    SELECT
        'id' AS 'field/@name',
        id AS 'field',
        '',
        'version' AS 'field/@name',
        version AS 'field',
        '',
        'property' AS 'field/@name',
        property AS 'field',
        '',
        ... and so on ....
    FROM Person.Person
    FOR XML PATH('row'),ROOT('resultset')
    

    这是确保列名用作&lt;field&gt; 元素上的name 属性所必需的,并且空字符串是必需的,这样SQL XML 解析器就不会混淆哪个name 属性属于什么元素……

    【讨论】:

    • 我担心这样的事情会成为答案!不过,它就像一个魅力,感谢您的快速响应。
    【解决方案2】:

    您无需将列指定为常量即可执行此操作,这样您也可以使用select *。它比 marc_s 提供的答案要复杂一些,执行起来会慢很多。

    select (
           select T.X.value('local-name(.)', 'nvarchar(128)') as '@name',
                  T.X.value('text()[1]', 'nvarchar(max)') as '*'
           from C.X.nodes('/X/*') as T(X)
           for xml path('field'), type
           )
    from (
         select (
                select T.*
                for xml path('X'), type
                ) as X
         from dbo.YourTable as T
         ) as C
    for xml path('row'), root('resultset')
    

    SQL Fiddle

    该查询创建了一个派生表,其中每一行都有一个如下所示的 XML:

    <X>
      <ID>1</ID>
      <Col1>1</Col1>
      <Col2>2014-08-21</Col2>
    </X>
    

    然后使用 nodes()local-name(.) 将 XML 切碎以创建您想要的形状。

    【讨论】:

      【解决方案3】:

      您的 SELECT 语句需要看起来像这样

      SELECT
          'id' AS [field/@name],
          id AS field,
          'version' AS [field/@name],
          version AS field,
          'property' AS [field/@name],
          property AS field,
          'release_date' AS [field/@name],
          release_date AS field,
          'territory_code' AS [field/@name],
          territory_code AS field,
          'territory_description' AS [field/@name],
          territory_description AS field,
          'currency_code' AS [field/@name],
          currency_code AS field
      

      【讨论】:

      • 这将不会按原样工作.....你会得到一个错误:Msg 6852, Level 16, State 1, Line 1 - Attribute-centric column 'field/@name' must not come after a non-attribute-centric sibling in XML hierarchy in FOR XML PATH.
      • 你是对的。我无法针对任何内容运行该语句来验证语法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多