我正在试图弄清楚如何查询生成如下所示的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>
答案 0 :(得分: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元素名称。例如,您可以在列名称中没有任何空格。
答案 1 :(得分:1)
我不认为只使用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>
您需要在每个属性之间选择“空”列,以避免所有列值都插入到单个<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" />