Create XML with variable element names from a data table with values and names

前端 未结 2 940
北恋
北恋 2020-12-21 20:08

I wasn\'t able to find a relevant post, so I decided to ask.

I have the following table in my SQL Server database:

ID       attname    value 
-------         


        
2条回答
  •  北荒
    北荒 (楼主)
    2020-12-21 20:44

    This is not possible normally. SQL Server does not support variable column aliases for your output. But there are workarounds:

    string concatenation

    The approach is a bit ugly, as I normally would not prefer to create XML via string concatenation. But by wrapping the value with a SELECT FOR XML PATH itself, this is even stable with forbidden characters like <> 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'' AS XML)
            FROM @tbl AS tbl
            WHERE tbl.ID=DistinctIDs.ID
            FOR XML PATH(''),TYPE
           )
    FROM DistinctIDs
    FOR XML PATH('Message')
    

    The result

    
      N
      IRVTGB2X
      104650.2000
      USD
      
      
      IRVTBEBB
    
    

    dynamic SQL

    You could build the full statement dynamically and use EXEC(@cmd) to execute it. Something like this:

    (Attention!!: The SELECT TOP 1 to get the ID is not appropriate for actual data!)

    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)
    

提交回复
热议问题