使用 FOR XML PATH 输出多个兄弟元素
Using FOR XML PATH to output Multiple Sibling Elements
我正在尝试从数据库中为查询结果中的每一行生成如下所示的 XML:
<Message>
<Header>
<MessageName>MyMessage</MessageName>
<TimeStamp>2017-03-31T14:32:48</TimeStamp>
<TrackingNum>1</TrackingNum>
</Header>
<Body>
<Activity>
<GUID>SomeGUID</GUID>
<OrderNum>3242432<OrderNum/>
<OrderDate>20160331143248</OrderDate>
</Activity>
</Body>
</Message>
我的查询如下所示:
SELECT
(SELECT DISTINCT top 20
[GUID],
OrderNum,
OrderDate,
FROM TableA
For XML PATH('Activity'), Type
) as Body
For XML path('Message'), TYPE
此查询输出包含在 <Message><Body>
标记内的所有行,只有一个包含所有内容的 XML 的单元格。我不知道在哪里包含 <Header>
部分的信息。
上面的查询产生以下结果,即 incorrect/incomplete:
<Message>
<Body>
<Activity>
<GUID>sdlksdkljsdkl</GUID>
<OrderNum>23423423</OrderNum>
<OrderDate>20160431143248</OrderDate>
</Activity>
<Activity>
<GUID>sdfsdfsw4erw</GUID>
<OrderNum>45560900</OrderNum>
<OrderDate>20160531143248</OrderDate>
</Activity>
<Activity>
<GUID>retertertwew</GUID>
<OrderNum>873409384</OrderNum>
<OrderDate>20160631143248</OrderDate>
</Activity>
</Body>
</Message>
我们如何将 Header 部分附加在 <Body>
标记之前,同时将输出分成多行?感谢您的任何帮助。
编辑:
Body/Activity
元素的模拟数据:
GUID OrderNum OrderDate
AAAA 1000 2017-04-13 12:00
BBBB 2000 2017-04-13 12:00
CCCC 3000 2017-04-13 12:00
我正在尝试将每一行都放在自己的 xml 中,就像上面的第一个 XML 块一样。
只需将 Header 添加为 XML-typed 列:
DECLARE @tbl TABLE([GUID] UNIQUEIDENTIFIER,OrderNum BIGINT, OrderDate DATETIME);
INSERT INTO @tbl VALUES(NEWID(),1111111,{ts'2001-01-01 01:00:00'})
,(NEWID(),2222222,{ts'2002-02-02 02:00:00'})
,(NEWID(),3333333,{ts'2003-03-03 03:00:00'});
SELECT
(
SELECT 'SomeMessageName' AS MessageName
,GETDATE() AS [TimeStamp]
,1 AS TraxingNum
FOR XML PATH('Header'),TYPE
)
,(
SELECT DISTINCT top 20
[GUID],
OrderNum,
OrderDate
FROM @tbl AS TableA
For XML PATH('Activity'), Type
) as Body
For XML path('Message'),TYPE;
结果
<Message>
<Header>
<MessageName>SomeMessageName</MessageName>
<TimeStamp>2017-04-13T10:20:09</TimeStamp>
<TraxingNum>1</TraxingNum>
</Header>
<Body>
<Activity>
<GUID>79DE31D2-4727-4880-BB11-72564AE707B0</GUID>
<OrderNum>3333333</OrderNum>
<OrderDate>2003-03-03T03:00:00</OrderDate>
</Activity>
<Activity>
<GUID>A9410295-5C78-4EC8-A904-8CB1D10563CF</GUID>
<OrderNum>2222222</OrderNum>
<OrderDate>2002-02-02T02:00:00</OrderDate>
</Activity>
<Activity>
<GUID>3192B87D-7C1A-4B95-A477-E10D2FC2845F</GUID>
<OrderNum>1111111</OrderNum>
<OrderDate>2001-01-01T01:00:00</OrderDate>
</Activity>
</Body>
</Message>
提示
- 在您的示例中,您的日期是这样的
20160531143248
。您应该始终在 XML 中使用 ISO8601 。否则,当您尝试阅读本文时,您会感到额外的痛苦。
- 使用没有
ORDER BY
的 TOP
是 - 嗯 - 至少是危险的......(你看,我的结果中的顺序不是预期的顺序?)
更新
根据你的评论,我认为你正在寻找其中之一(用我上面的 mock-up table 测试它们):
SELECT
'SomeMessageName' AS [Header/MessageName]
,GETDATE() AS [Header/TimeStamp]
,1 AS [Header/TraxingNum]
,[GUID] AS [Body/GUID]
,OrderNum AS [Body/OrderNum]
,OrderDate AS [Body/OrderDate]
FROM @tbl AS TableA
FOR XML PATH('Message'),TYPE;
SELECT
(SELECT
'SomeMessageName' AS [Header/MessageName]
,GETDATE() AS [Header/TimeStamp]
,1 AS [Header/TraxingNum]
,[GUID] AS [Body/GUID]
,OrderNum AS [Body/OrderNum]
,OrderDate AS [Body/OrderDate]
FOR XML PATH('Message'),TYPE)
FROM @tbl AS TableA;
我正在尝试从数据库中为查询结果中的每一行生成如下所示的 XML:
<Message>
<Header>
<MessageName>MyMessage</MessageName>
<TimeStamp>2017-03-31T14:32:48</TimeStamp>
<TrackingNum>1</TrackingNum>
</Header>
<Body>
<Activity>
<GUID>SomeGUID</GUID>
<OrderNum>3242432<OrderNum/>
<OrderDate>20160331143248</OrderDate>
</Activity>
</Body>
</Message>
我的查询如下所示:
SELECT
(SELECT DISTINCT top 20
[GUID],
OrderNum,
OrderDate,
FROM TableA
For XML PATH('Activity'), Type
) as Body
For XML path('Message'), TYPE
此查询输出包含在 <Message><Body>
标记内的所有行,只有一个包含所有内容的 XML 的单元格。我不知道在哪里包含 <Header>
部分的信息。
上面的查询产生以下结果,即 incorrect/incomplete:
<Message>
<Body>
<Activity>
<GUID>sdlksdkljsdkl</GUID>
<OrderNum>23423423</OrderNum>
<OrderDate>20160431143248</OrderDate>
</Activity>
<Activity>
<GUID>sdfsdfsw4erw</GUID>
<OrderNum>45560900</OrderNum>
<OrderDate>20160531143248</OrderDate>
</Activity>
<Activity>
<GUID>retertertwew</GUID>
<OrderNum>873409384</OrderNum>
<OrderDate>20160631143248</OrderDate>
</Activity>
</Body>
</Message>
我们如何将 Header 部分附加在 <Body>
标记之前,同时将输出分成多行?感谢您的任何帮助。
编辑:
Body/Activity
元素的模拟数据:
GUID OrderNum OrderDate
AAAA 1000 2017-04-13 12:00
BBBB 2000 2017-04-13 12:00
CCCC 3000 2017-04-13 12:00
我正在尝试将每一行都放在自己的 xml 中,就像上面的第一个 XML 块一样。
只需将 Header 添加为 XML-typed 列:
DECLARE @tbl TABLE([GUID] UNIQUEIDENTIFIER,OrderNum BIGINT, OrderDate DATETIME);
INSERT INTO @tbl VALUES(NEWID(),1111111,{ts'2001-01-01 01:00:00'})
,(NEWID(),2222222,{ts'2002-02-02 02:00:00'})
,(NEWID(),3333333,{ts'2003-03-03 03:00:00'});
SELECT
(
SELECT 'SomeMessageName' AS MessageName
,GETDATE() AS [TimeStamp]
,1 AS TraxingNum
FOR XML PATH('Header'),TYPE
)
,(
SELECT DISTINCT top 20
[GUID],
OrderNum,
OrderDate
FROM @tbl AS TableA
For XML PATH('Activity'), Type
) as Body
For XML path('Message'),TYPE;
结果
<Message>
<Header>
<MessageName>SomeMessageName</MessageName>
<TimeStamp>2017-04-13T10:20:09</TimeStamp>
<TraxingNum>1</TraxingNum>
</Header>
<Body>
<Activity>
<GUID>79DE31D2-4727-4880-BB11-72564AE707B0</GUID>
<OrderNum>3333333</OrderNum>
<OrderDate>2003-03-03T03:00:00</OrderDate>
</Activity>
<Activity>
<GUID>A9410295-5C78-4EC8-A904-8CB1D10563CF</GUID>
<OrderNum>2222222</OrderNum>
<OrderDate>2002-02-02T02:00:00</OrderDate>
</Activity>
<Activity>
<GUID>3192B87D-7C1A-4B95-A477-E10D2FC2845F</GUID>
<OrderNum>1111111</OrderNum>
<OrderDate>2001-01-01T01:00:00</OrderDate>
</Activity>
</Body>
</Message>
提示
- 在您的示例中,您的日期是这样的
20160531143248
。您应该始终在 XML 中使用 ISO8601 。否则,当您尝试阅读本文时,您会感到额外的痛苦。 - 使用没有
ORDER BY
的TOP
是 - 嗯 - 至少是危险的......(你看,我的结果中的顺序不是预期的顺序?)
更新
根据你的评论,我认为你正在寻找其中之一(用我上面的 mock-up table 测试它们):
SELECT
'SomeMessageName' AS [Header/MessageName]
,GETDATE() AS [Header/TimeStamp]
,1 AS [Header/TraxingNum]
,[GUID] AS [Body/GUID]
,OrderNum AS [Body/OrderNum]
,OrderDate AS [Body/OrderDate]
FROM @tbl AS TableA
FOR XML PATH('Message'),TYPE;
SELECT
(SELECT
'SomeMessageName' AS [Header/MessageName]
,GETDATE() AS [Header/TimeStamp]
,1 AS [Header/TraxingNum]
,[GUID] AS [Body/GUID]
,OrderNum AS [Body/OrderNum]
,OrderDate AS [Body/OrderDate]
FOR XML PATH('Message'),TYPE)
FROM @tbl AS TableA;