Create HTML Table with SQL FOR XML

前端 未结 8 1428
夕颜
夕颜 2020-11-22 08:34

I\'m creating a HL7 Continuity of Care Document (CCD) using FOR XML statements in SQL Server 2008 R2.

I\'ve done A LOT with this method, but this is the first time I

8条回答
  •  心在旅途
    2020-11-22 08:54

    This is a generic solution with a FUNCTION on XML-base using FLWOR

    It will transform any SELECT into a XHTML table.

    It works (tested) with 2008R2+, but I'm pretty sure this would work on 2008, might be even on 2005, too. If someone wants to verify this, please leave a comment. Thx

    The following function replaces all the various functions I provided before (see the previous version if needed)

    CREATE FUNCTION dbo.CreateHTMLTable
    (
        @SelectForXmlPathRowElementsXsinil XML
       ,@tblClass VARCHAR(100) --NULL to omit this class
       ,@thClass VARCHAR(100)  --same
       ,@tbClass VARCHAR(100)  --same
    )
    RETURNS XML
    AS
    BEGIN
    
    RETURN 
    (
        SELECT @tblClass AS [@class]  
        ,@thClass AS [thead/@class]
        ,@SelectForXmlPathRowElementsXsinil.query(
                  N'let $first:=/row[1]
                    return 
                     
                    {
                    for $th in $first/*
                    return {if(not(empty($th/@caption))) then xs:string($th/@caption) else local-name($th)}
                    }
                    ') AS thead
        ,@tbClass AS [tbody/@class]
        ,@SelectForXmlPathRowElementsXsinil.query(
                   N'for $tr in /row
                     return 
                     {$tr/@class}
                     {
                     for $td in $tr/*
                     return
                     if(empty($td/@link)) 
                     then {$td/@class}{string($td)}
                     else {$td/@class}{string($td)}
                     }
                     ') AS tbody
        FOR XML PATH('table'),TYPE
    ) 
    END
    GO
    

    The easiest call

    A mock-up table with some values

    DECLARE @tbl TABLE(ID INT, [Message] VARCHAR(100));
    INSERT INTO @tbl VALUES
     (1,'Value 1')
    ,(2,'Value 2');
    

    --The call must enclose the SELECT ... FOR XML in paranthesis!
    --click run snippet to see the result!

    SELECT dbo.CreateHTMLTable
    (
         (SELECT * FROM @tbl FOR XML PATH('row'),ELEMENTS XSINIL)
         ,NULL,NULL,NULL
    );
    

        
    ID Message
    1 Value 1
    2 Value 2

    If you need headers with blanks

    If your table contains a column with a blank in its name, or if you want to set a column's caption manually (multi langugage support!), or if you want to replace a CamelCaseName with an out-written caption, you can pass this as attribute:

    DECLARE @tbl2 TABLE(ID INT, [With Blank] VARCHAR(100));
    INSERT INTO @tbl2 VALUES
     (1,'Value 1')
    ,(2,'Value 2');
    
    SELECT dbo.CreateHTMLTable
    (
         (
         SELECT ID
               ,'The new name' AS [SomeOtherName/@caption] --set a caption 
               ,[With Blank] AS [SomeOtherName] 
         FROM @tbl2 FOR XML PATH('row'),ELEMENTS XSINIL
         )
         ,NULL,NULL,NULL
    );
    

    	
    ID The new name
    1 Value 1
    2 Value 2

    Full CSS-support and hyper-links

    You can use attributes to pass over a link or a row-based and even a value-based class to mark columns and even cells for CSS styling.

    --a mock-up table with a row based condition and hyper-links
    
    DECLARE @tbl3 TABLE(ID INT, [With blank] VARCHAR(100),Link VARCHAR(MAX),ShouldNotBeNull INT);
    INSERT INTO @tbl3 VALUES
     (1,'NoWarning',NULL,1)
    ,(2,'No Warning too','http://www.Link2.com',2)
    ,(3,'Warning','http://www.Link3.com',3)
    ,(4,NULL,NULL,NULL)
    ,(5,'Warning',NULL,5)
    ,(6,'One more warning','http://www.Link6.com',6);
    --The query adds an attribute Link to an element (NULL if not defined)
    SELECT dbo.CreateHTMLTable
    (
         (
         SELECT 
           CASE WHEN LEFT([With blank],2) != 'No' THEN 'warning' ELSE NULL END AS [@class]      --The first @class is the -class
          ,ID
          ,'center' AS [Dummy/@class]                                                    --a class within TestText (appeary always)
          ,Link AS [Dummy/@link]                                                         --a mark to pop up as link
          ,'New caption' AS [Dummy/@caption]                                             --a different caption
          ,[With blank] AS [Dummy]                                                       --blanks in the column's name must be tricked away...
          ,CASE WHEN ShouldNotBeNull IS NULL THEN 'MarkRed' END AS [ShouldNotBeNull/@class] --a class within ShouldNotBeNull (appears only if needed)
          ,'Should not be null' AS [ShouldNotBeNull/@caption]                             --a caption for a CamelCase-ColumnName
          ,ShouldNotBeNull
         FROM @tbl3 FOR XML PATH('row'),ELEMENTS XSINIL),'testTbl','testTh','testTb'
    );
    

    
    
    ID New caption Should not be null
    1 NoWarning 1
    2 No Warning too 2
    3 Warning 3
    4
    5 Warning 5
    6 One more warning 6

    As a possible enhancement one might pass in a one-row-footer with aggregated values as additional parameter and append it as

提交回复
热议问题