2

我试图弄清楚如何查询生成如下所示的 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>
4

2 回答 2

4

在不指定列名的情况下执行此操作有点棘手但可行。
要使用它,您需要替换@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 元素名。例如,您可以在列名中没有任何空格。

于 2012-03-03T17:57:37.743 回答
1

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

我的查询在这里使用FOR XML PATHSQL Server 2005 和更新版本中可用的构造:

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>

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

    <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" />
于 2012-03-03T09:05:49.597 回答