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

前端 未结 2 926
北恋
北恋 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:40

    As far as I know, there is no control over the way the output is generated in the FOR XML output, aside from manipulating the data types and field names in the query.

    You would need to generate it as it normally does, then reprocess it possibly with XSLT to make it into what you want.

    This could actually be done on the server if it has support for the CLR.

    0 讨论(0)
  • 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'</' + attname + N'>' AS XML)
            FROM @tbl AS tbl
            WHERE tbl.ID=DistinctIDs.ID
            FOR XML PATH(''),TYPE
           )
    FROM DistinctIDs
    FOR XML PATH('Message')
    

    The result

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

    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)
    
    0 讨论(0)
提交回复
热议问题