SQL Server 使用通用字段元素生成 XML

Posted

技术标签:

【中文标题】SQL Server 使用通用字段元素生成 XML【英文标题】:SQL Server generating XML with generic field elements 【发布时间】: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')

我错过了什么?谢谢。

【问题讨论】:

【参考方案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. 你是对的。我无法针对任何内容运行该语句来验证语法。

以上是关于SQL Server 使用通用字段元素生成 XML的主要内容,如果未能解决你的问题,请参考以下文章

(轉載)sql server xml字段的操作

使用使用 Excel 标记的 SQL Server 生成 XML

为OCI上的通用Windows Server实例生成密码

如何在 Sql Server 中使用动态生成的字段进行添加?

如何从XML *向SQL Server DATE字段*中插入NULL

如何使用 SQL 将 Sql Server DateTime 转换为通用时间