[英]A special case of XML generation
我正在使用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">
我能夠以您所需的格式輸出以下內容:
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>
您可以將表轉換為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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.