【问题标题】:How can I query SQL Server and generate XML with column names and values as attributes如何查询 SQL Server 并以列名和值作为属性生成 XML
【发布时间】:2012-03-03 06:12:36
【问题描述】:

我试图弄清楚如何查询生成如下所示的 xml 的表: (这是 AdventureWorks 数据库中的一个示例。

我可以很容易地将列名作为元素获取,但是是否可以将列名和值都作为属性?我试图弄清楚如何以通用方式执行此操作,所以我不想使用 FOR EXPLICIT 对列名进行硬编码

    <TABLE name="StateProvince">
        <ROW>
            <COL name="StateProvinceID" value="1" />
            <COL name="StateProvinceCode" value="AB" />
            <COL name="CountryRegionCode" value="CA" />
            <COL name="IsOnlyStateProvinceFlag" value="0" />
            <COL name="Name" value="Alberta" />
            <COL name="TerritoryID" value="6" />
            <COL name="rowguid" value="298C2880-AB1C-4982-A5AD-A36EB4BA0D34" />
            <COL name="ModifiedDate" value="2004-03-11T10:17:21.587" />
        </ROW>
    </TABLE>

【问题讨论】:

    标签: sql-server-2008 sqlxml


    【解决方案1】:

    在不指定列名的情况下执行此操作有点棘手但可行。
    要使用它,您需要将@T 替换为您的表名,并将表名常量'StateProvince' 更改为您的表名。

    declare @T table
    (
      StateProvinceID int,
      StateProvinceCode char(2),
      CountryRegionCode char(2),
      IsOnlyStateProvinceFlag int,
      Name varchar(50),
      TerritoryID int,
      rowguid uniqueidentifier,
      ModifiedDate datetime
    )
    
    insert into @T values
    (1, 'AB', 'CA', 0, 'Alberta', 6, '298C2880-AB1C-4982-A5AD-A36EB4BA0D34', '2004-03-11T10:17:21.587'),
    (2, 'AB', 'CA', 0, 'Alberta', 6, '298C2880-AB1C-4982-A5AD-A36EB4BA0D34', '2004-03-11T10:17:21.587')
    
    select 'StateProvince' as [@name],
      (
        select 
          (
            select T3.N.value('local-name(.)', 'sysname') as [@name],
                   T3.N.value('.', 'nvarchar(max)') as [@value]
            from (
                   select T1.*
                   for xml path(''), type
                 ) T2(N)
              cross apply T2.N.nodes('*') as T3(N)       
            for xml path('COL'), root('ROW'), type
          )         
        from @T as T1
        for xml path(''), type
      )
    for xml path('TABLE')  
    

    结果:

    <TABLE name="StateProvince">
      <ROW>
        <COL name="StateProvinceID" value="1" />
        <COL name="StateProvinceCode" value="AB" />
        <COL name="CountryRegionCode" value="CA" />
        <COL name="IsOnlyStateProvinceFlag" value="0" />
        <COL name="Name" value="Alberta" />
        <COL name="TerritoryID" value="6" />
        <COL name="rowguid" value="298C2880-AB1C-4982-A5AD-A36EB4BA0D34" />
        <COL name="ModifiedDate" value="2004-03-11T10:17:21.587" />
      </ROW>
      <ROW>
        <COL name="StateProvinceID" value="2" />
        <COL name="StateProvinceCode" value="AB" />
        <COL name="CountryRegionCode" value="CA" />
        <COL name="IsOnlyStateProvinceFlag" value="0" />
        <COL name="Name" value="Alberta" />
        <COL name="TerritoryID" value="6" />
        <COL name="rowguid" value="298C2880-AB1C-4982-A5AD-A36EB4BA0D34" />
        <COL name="ModifiedDate" value="2004-03-11T10:17:21.587" />
      </ROW>
    </TABLE>
    

    注意:表中的列名必须是有效的 XML 元素名。例如,列名中可以不包含任何空格。

    【讨论】:

    • 谢谢 Mikael,我以前见过类似的东西,希望我错过了一些更容易的东西。 :-)
    【解决方案2】:

    我认为仅使用 SQL Server 的功能无法实现 100% 的目标 - 你可以接近,但不能 100%。

    我在此处的查询使用 SQL Server 2005 及更高版本中可用的 FOR XML PATH 构造:

    SELECT 
        [StateProvinceID] AS 'COL/@StateProvinceID',
        '',
        [StateProvinceCode] AS 'COL/@StateProvinceCode',
        '',
        [CountryRegionCode] AS 'COL/@CountryRegionCode',
        '',
        [IsOnlyStateProvinceFlag] AS 'COL/@IsOnlyStateProvinceFlag',
        '',
        [Name] AS 'COL/@Name',
        '',
        [TerritoryID] AS 'COL/@TerritoryID',
        '',
        [rowguid] AS 'COL/@rowguid',
        '',
        [ModifiedDate] AS 'COL/@ModifiedDate'
      FROM [Person].[StateProvince]
      FOR XML PATH('ROW'), ROOT('TABLE')
    

    这会产生类似这样的 XML:

    <TABLE>
      <ROW>
        <COL StateProvinceID="1" />
        <COL StateProvinceCode="AB " />
        <COL CountryRegionCode="CA" />
        <COL IsOnlyStateProvinceFlag="0" />
        <COL Name="Alberta" />
        <COL TerritoryID="6" />
        <COL rowguid="298C2880-AB1C-4982-A5AD-A36EB4BA0D34" />
        <COL ModifiedDate="2008-03-11T10:17:21.587" />
      </ROW>
      <ROW>
        <COL StateProvinceID="2" />
        <COL StateProvinceCode="AK " />
        <COL CountryRegionCode="US" />
        <COL IsOnlyStateProvinceFlag="0" />
        <COL Name="Alaska" />
        <COL TerritoryID="1" />
        <COL rowguid="5B7B8462-A888-4E0B-A3E1-7278F8AF107E" />
        <COL ModifiedDate="2008-03-11T10:17:21.587" />
      </ROW>
      ..........
    </TABLE>
    

    您需要在每个属性之间选择“空”列,以避免所有列值都卡在单个 &lt;COL .... /&gt; 元素中,如下所示:

        <COL StateProvinceID="2"  
             StateProvinceCode="AK "  
             CountryRegionCode="US"    
             IsOnlyStateProvinceFlag="0"  
             Name="Alaska"  
             TerritoryID="1" 
             rowguid="5B7B8462-A888-4E0B-A3E1-7278F8AF107E"  
             ModifiedDate="2008-03-11T10:17:21.587" />
    

    【讨论】:

      猜你喜欢
      • 2013-10-10
      • 1970-01-01
      • 2012-10-06
      • 2017-01-30
      • 2011-07-04
      • 2012-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多