尝试在SQL 2012中使用FOR XML。需要有这样的结果:
<Loader xmlns:xsi="url1" xmlns="url2">
<Buy_New>
<Ticker>IBM</Ticker>
<Acct>12345</Acct>
<Qty>10</Qty>
</Buy_New>
<Sell_New>
<Ticker>MSFT</Ticker>
<Acct>12345</Acct>
<Qty>15</Qty>
</Sell_New>
<Buy_New>
<Ticker>IBM</Ticker>
<Acct>12345</Acct>
<Qty>10</Qty>
</Buy_New>
</Loader>
在这里查看,MSDN等,我没有看到在我的查询中动态更改<Buy_New>
和<Sell_New>
(我有大约20种不同类型可用)的方法,我已经探索过使用FOR XML PATH和FOR XML EXPLICIT,但两者似乎都需要静态元素标记。
有没有办法从查询中的行中驱动标记?
@Jon C当然:这就是我所拥有的:
SELECT
(
SELECT
Investment1 as Investment,
EventDate1 as Date,
Quantity1 as Quantity
FROM #temptable e1 where e1.temp_id = e.temp_id
FOR XML PATH(''),TYPE
) AS 'DYNAMICTAG'
FROM #temptable e
FOR XML PATH(''), ROOT('Loader')`
以下是结果示例。 DYNAMICTAG是需要更改为<Buy_New>
,<Sell_New>
等的部分。
<Loader>
<DYNAMICTAG>
<Investment>XYZ</Investment>
<Date>2015-05-08T00:00:00</Date>
<Quantity>50</Quantity>
</DYNAMICTAG>
<DYNAMICTAG>
<Investment>ABC</Investment>
<Date>2015-05-08T00:00:00</Date>
<Quantity>10</Quantity>
</DYNAMICTAG>
<DYNAMICTAG>
<Investment>CSCO</Investment>
<Date>2015-05-08T00:00:00</Date>
<Quantity>50</Quantity>
</DYNAMICTAG>
<DYNAMICTAG>
<Investment>IBM</Investment>
<Date>2015-05-08T00:00:00</Date>
<Quantity>30</Quantity>
</DYNAMICTAG>
</Loader>
答案 0 :(得分:32)
我不确定确定标签是否应该“买新”的条件。或者&#39; sell_new&#39;,但这可能适合您:
SELECT
(
SELECT
Investment1 as Investment,
EventDate1 as Date,
Quantity1 as Quantity
FROM #temptable e1 where e1.temp_id = e.temp_id
AND (SOME CONDITION FOR 'Buy_New')
FOR XML PATH('Buy_New'),TYPE
) ,
(
SELECT
Investment1 as Investment,
EventDate1 as Date,
Quantity1 as Quantity
FROM #temptable e1 where e1.temp_id = e.temp_id
AND (SOME CONDITION FOR 'Sell_New')
FOR XML PATH('Sell_New'),TYPE
)
FROM #temptable e
FOR XML PATH(''), ROOT('Loader')
GO
编辑:
根据你的回答,我知道你需要更有活力的东西。这可能不是您正在寻找的优雅解决方案,但它可以完成工作而无需对每个元素进行硬编码:
首先,创建一个表来存储所需的动态元素名称:
create table elements (id int, name nvarchar(20))
insert into elements (id, name) values (1, 'sell_new')
insert into elements (id, name) values (2, 'buy_new')
insert into elements (id, name) values (3, 'other_new')
然后是解决方法:
SELECT cast('<' + e.name +'>' +
cast(
(
SELECT
Investment AS 'Investment',
EventDate as 'Date',
Quantity AS 'Quantity'
FROM temptable t1
WHERE t1.investment = t.investment
FOR XML PATH(''),TYPE
) as varchar(max))
+ '</' + e.name +'>' as xml)
from temptable t
JOIN elements e ON e.id = t.RecordType
order by investment
for xml path(''), root('Loader')
结果:
<Loader>
<sell_new>
<Investment>abc</Investment>
<Quantity>456</Quantity>
</sell_new>
<buy_new>
<Investment>cde</Investment>
<Quantity>789</Quantity>
</buy_new>
<sell_new>
<Investment>efg</Investment>
<Quantity>0</Quantity>
</sell_new>
</Loader>
答案 1 :(得分:4)
精选答案(基于@ JonC建议使用CAST,但不需要单独的表来保存标签的所有不同可能性)
SELECT
(
SELECT
CAST('<' + t1.RecordType + '>' +
CAST(
(
SELECT
t2.Portfolio1 AS 'Portfolio',
t2.Qty1 AS 'Qty',
t2.Price AS 'Price',
FROM #temptable t2
WHERE t2.temptable_id = t1.temptable_id
FOR XML PATH(''),TYPE
) as varchar(max))
+ '</' + t1.RecordType + '>' as xml)
from #temptable t1
FOR XML PATH(''), TYPE
) AS 'TranRecords'
FOR XML PATH(''), ROOT('Loader')
答案 2 :(得分:1)
可能有一个更优雅的解决方案(我希望其他人发布它!)但我认为雅各布的博客在这里有一个可行的解决方案:
FOR XML PATH – Yet another shaping example using FOR XML PATH
代码示例在这里:
SELECT
(
SELECT
Investment AS 'Investment',
Quantity AS 'Quantity',
Price AS 'Price'
FROM #temptable
WHERE RecordType = 'Buy'
FOR XML PATH('Buy_New'),TYPE
) AS 'TransactionRecords',
(
SELECT
Investment AS 'Investment',
Quantity AS 'Quantity',
Price AS 'Price'
FROM #temptable
WHERE RecordType = 'Sell'
FOR XML PATH('Sell_New'),TYPE
) AS 'TransactionRecords',
(
SELECT
Investment AS 'Investment',
Quantity AS 'Quantity',
Price AS 'Price'
FROM #temptable
WHERE RecordType = 'Short'
FOR XML PATH('Short_New'),TYPE
) AS 'TransactionRecords',
(
SELECT
Investment AS 'Investment',
Quantity AS 'Quantity',
Price AS 'Price'
FROM #temptable
WHERE RecordType = 'Cover'
FOR XML PATH('Cover_New'),TYPE
) AS 'TransactionRecords'
FOR XML PATH(''), ROOT('GenevaLoader')