使用值和名称从数据表创建具有可变元素名称的XML

时间:2016-07-13 19:09:14

标签: sql-server xml dynamic key-value keyvaluepair

我无法找到相关的帖子,所以我决定问。

我的SQL Server数据库中有以下表格:

ID       attname    value 
---------------------------------
22405543 blktradind N 
22405543 brkref     IRVTGB2X
22405543 buyamt     104650.2000 
22405543 buycurref  USD 
22405543 Buy53ref 
22405543 Buy56ref 
22405543 Buy57ref   IRVTBEBB

如何通过将FOR XML变体用于基于" attname"的动态XML结果来转换此表?每条消息都有?

对于上面的摘录,所需的结果将是:

<Message id=22405543>
  <blktradind>N</blktradind>
  <brkref>IRVTGB2X</brkref>
  <buyamt>104650.2000</buyamt>
  <buycurref>USD</buycurref>
  <buy53ref />
  <buy56ref />
  <buy57ref>IRVTBEBB</buy57ref>
</Message>

由于

2 个答案:

答案 0 :(得分:1)

通常不可能。 SQL Server不支持输出的变量列别名。但有一些解决方法:

字符串连接

这种方法有点难看,因为我通常不喜欢通过字符串连接来创建XML。但是通过用SELECT FOR XML PATH本身包装值,这对于像<> or &这样的禁用字符来说甚至是稳定的。

DECLARE @tbl TABLE(ID BIGINT,attname NVARCHAR(100),value NVARCHAR(100));
INSERT INTO @tbl VALUES 
 (22405543,'blktradind','N') 
,(22405543,'brkref','IRVTGB2X') 
,(22405543,'buyamt','104650.2000')  
,(22405543,'buycurref','USD')  
,(22405543,'Buy53ref',NULL) 
,(22405543,'Buy56ref',NULL) 
,(22405543,'Buy57ref','IRVTBEBB');

WITH DistinctIDs AS
(
    SELECT DISTINCT ID FROM @tbl
)
SELECT ID AS [@id]
      ,(
        SELECT CAST(N'<' + attname + N'>' + ISNULL((SELECT value AS [*] FOR XML PATH('')),N'') + N'</' + attname + N'>' AS XML)
        FROM @tbl AS tbl
        WHERE tbl.ID=DistinctIDs.ID
        FOR XML PATH(''),TYPE
       )
FROM DistinctIDs
FOR XML PATH('Message')

结果

<Message id="22405543">
  <blktradind>N</blktradind>
  <brkref>IRVTGB2X</brkref>
  <buyamt>104650.2000</buyamt>
  <buycurref>USD</buycurref>
  <Buy53ref />
  <Buy56ref />
  <Buy57ref>IRVTBEBB</Buy57ref>
</Message>

动态SQL

您可以动态构建完整语句并使用EXEC(@cmd)来执行它。像这样:

注意!! :获取ID的SELECT TOP 1不适合实际数据!)

DECLARE  @cmd NVARCHAR(MAX)=
(
    SELECT 'SELECT ''' + CAST((SELECT TOP 1 ID FROM @tbl) AS NVARCHAR(100)) + ''' AS [@id] ' 
    + (
    SELECT ',''' + ISNULL(value,'') + ''' AS [' + attname + ']'
    FROM  @tbl
    FOR XML PATH('')
    )
    + ' FOR XML PATH(''Message'')'
);
EXEC(@cmd)

答案 1 :(得分:0)

据我所知,除了操纵查询中的数据类型和字段名称外,无法控制FOR XML输出中输出的生成方式。

您需要像往常一样生成它,然后使用XSLT重新处理它,使其成为您想要的。

如果它支持CLR,实际上可以在服务器上完成。