我正在使用SQL Server 2012 SP1 Express:
如何生成此XML?
<Batch CodeGeneratorId="1234" BatchNumber="Batch0001" OrderNumber="Order0001" TimeStamp="2012-01-01 05:15:00">
<BatchDetail Key="Name" Value="MyName" />
<BatchDetail Key="Stu" Value="FA20123.01" />
<BatchDetail Key="Com_L1" Value="19898" />
<BatchDetail Key="Dec_L1" Value="24" />
<BatchDetail Key="Agg_L1" Value="18520" />
</Batch>
使用BATCH_DATA
表上的数据:
ID | Key | Value
----+------------------+-------------
1 | CodeGeneratorId | 1234
2 | BatchNumber | Batch0001
3 | OrderNumber | Order0001
4 | Name | MyName
5 | Stu | FA20123.01
6 | Com_L1 | 19898
7 | Dec_L1 | 24
8 | Agg_L1 | 18520
我的问题是我不知道如何生成这部分:
<Batch CodeGeneratorId="1234" BatchNumber="Batch0001"
OrderNumber="Order0001" TimeStamp="2012-01-01 05:15:00">
答案 0 :(得分:1)
我能够以您需要的格式输出以下内容:
CREATE TABLE #T ([ID] INT, [Key] VARCHAR(15), [Value] VARCHAR(10));
INSERT INTO #T ([ID], [Key], [Value])
VALUES
(1, 'CodeGeneratorId', '1234'),
(2, 'BatchNumber', 'Batch0001'),
(3, 'OrderNumber', 'Order0001'),
(4, 'Name', 'MyName'),
(5, 'Stu', 'FA20123.01'),
(6, 'Com_L1', '19898'),
(7, 'Dec_L1', '24'),
(8, 'Agg_L1', '18520');
SELECT [Batch].[CodeGeneratorId],
[Batch].[BatchNumber],
[Batch].[OrderNumber],
BatchDetails.[Key],
BatchDetails.Value
FROM ( SELECT [CodeGeneratorId], [BatchNumber], [OrderNumber]
FROM ( SELECT [Key], [Value]
FROM #T
WHERE [Key] IN ('CodeGeneratorId', 'BatchNumber', 'OrderNumber')
) t
PIVOT
( MAX(Value)
FOR [Key] IN ([CodeGeneratorId], [BatchNumber], [OrderNumber])
) pvt
) AS [Batch]
CROSS JOIN
( SELECT [Key], Value
FROM #T AS BatchDetail
WHERE [Key] NOT IN ('CodeGeneratorId', 'BatchNumber', 'OrderNumber')
) AS BatchDetails
FOR XML AUTO;
它本质上是一个两阶段的过程,首先创建标题:
SELECT [CodeGeneratorId], [BatchNumber], [OrderNumber]
FROM ( SELECT [Key], [Value]
FROM #T
WHERE [Key] IN ('CodeGeneratorId', 'BatchNumber', 'OrderNumber')
) t
PIVOT
( MAX(Value)
FOR [Key] IN ([CodeGeneratorId], [BatchNumber], [OrderNumber])
) pvt
FOR XML AUTO;
会给:
<pvt CodeGeneratorId="1234" BatchNumber="Batch0001" OrderNumber="Order0001" />
SELECT [Key], Value
FROM #T AS BatchDetail
WHERE [Key] NOT IN ('CodeGeneratorId', 'BatchNumber', 'OrderNumber')
FOR XML AUTO;
会给:
<BatchDetail Key="Name" Value="MyName" />
<BatchDetail Key="Stu" Value="FA20123.01" />
<BatchDetail Key="Com_L1" Value="19898" />
<BatchDetail Key="Dec_L1" Value="24" />
<BatchDetail Key="Agg_L1" Value="18520" />
所以这只是将两者结合起来的问题。如果您实际上有一个要链接的字段,则可能需要将其从交叉连接转换为交叉应用:
CREATE TABLE #T2 ([ID] INT, Col INT, [Key] VARCHAR(15), [Value] VARCHAR(10));
INSERT INTO #T2 ([ID], Col, [Key], [Value])
VALUES
(1, 1, 'CodeGeneratorId', '1234'),
(2, 1, 'BatchNumber', 'Batch0001'),
(3, 1, 'OrderNumber', 'Order0001'),
(4, 1, 'Name', 'MyName'),
(5, 1, 'Stu', 'FA20123.01'),
(6, 1, 'Com_L1', '19898'),
(7, 1, 'Dec_L1', '24'),
(8, 1, 'Agg_L1', '18520'),
(9, 2, 'CodeGeneratorId', '1255'),
(10, 2, 'BatchNumber', 'Batch0002'),
(11, 2, 'OrderNumber', 'Order0002'),
(12, 2, 'Name', 'MyName'),
(13, 2, 'Stu', 'FA20123.01'),
(14, 2, 'Com_L1', '19898'),
(15, 2, 'Dec_L1', '24'),
(16, 2, 'Agg_L1', '18520');
SELECT [Batch].[CodeGeneratorId],
[Batch].[BatchNumber],
[Batch].[OrderNumber],
BatchDetails.[Key],
BatchDetails.Value
FROM ( SELECT Col, [CodeGeneratorId], [BatchNumber], [OrderNumber]
FROM ( SELECT Col, [Key], [Value]
FROM #T2
WHERE [Key] IN ('CodeGeneratorId', 'BatchNumber', 'OrderNumber')
) t
PIVOT
( MAX(Value)
FOR [Key] IN ([CodeGeneratorId], [BatchNumber], [OrderNumber])
) pvt
) AS [Batch]
CROSS APPLY
( SELECT [Key], Value
FROM #T2 AS BatchDetail
WHERE [Key] NOT IN ('CodeGeneratorId', 'BatchNumber', 'OrderNumber')
AND BatchDetail.Col = Batch.Col
) AS BatchDetails
FOR XML AUTO;
会给你两个结果:
<Batch CodeGeneratorId="1234" BatchNumber="Batch0001" OrderNumber="Order0001">
<BatchDetails Key="Name" Value="MyName" />
<BatchDetails Key="Stu" Value="FA20123.01" />
<BatchDetails Key="Com_L1" Value="19898" />
<BatchDetails Key="Dec_L1" Value="24" />
<BatchDetails Key="Agg_L1" Value="18520" />
</Batch>
<Batch CodeGeneratorId="1255" BatchNumber="Batch0002" OrderNumber="Order0002">
<BatchDetails Key="Name" Value="MyName" />
<BatchDetails Key="Stu" Value="FA20123.01" />
<BatchDetails Key="Com_L1" Value="19898" />
<BatchDetails Key="Dec_L1" Value="24" />
<BatchDetails Key="Agg_L1" Value="18520" />
</Batch>
答案 1 :(得分:1)
您可以将表转换为XML,然后查询该XML以构建所需的XML。
select T.X.value('(/row[Key = "CodeGeneratorId"]/Value/text())[1]', 'varchar(50)') as [@CodeGeneratorId],
T.X.value('(/row[Key = "BatchNumber"]/Value/text())[1]', 'varchar(50)') as [@BatchNumber],
T.X.value('(/row[Key = "OrderNumber"]/Value/text())[1]', 'varchar(50)') as [@OrderNumber],
sysdatetime() as [@TimeStamp],
(
select R.X.value('(Key/text())[1]', 'varchar(50)') as [@Name],
R.X.value('(Value/text())[1]', 'varchar(50)') as [@Value]
from T.X.nodes('row') as R(X)
where R.X.value('(Key/text())[1]', 'varchar(50)') not in ('CodeGeneratorId', 'BatchNumber', 'OrderNumber')
for xml path('BatchDetail'), type
)
from (
select [Key],
Value
from T
for xml path('row'), type
) as T(X)
for xml path('Batch'), type