【问题标题】:Formating color in SQL Server using FOR XML PATH使用 FOR XML PATH 在 SQL Server 中格式化颜色
【发布时间】:2018-10-08 13:06:36
【问题描述】:

我已经使用过这种方法,但现在我必须根据值使用一些颜色。所以,我在一个表中有以下信息:

Material | Q1 | Q2
---------+----+-----
M1       | 10 | 5
M2       | 3  | 10
M3       | 15 | 15

当Q1低于Q2时我想染红色,当蓝色和黄色高时是相同的值。

CREATE TABLE #tempo
(
    q1 INT, q2 INT, name VARCHAR(10)
)

INSERT INTO #tempo (q1, q2, name)
VALUES (10, 5, 'low'), (10, 10, 'same'), (10, 20, 'high')

--SELECT * FROM #tempo

DECLARE @html varchar(MAX)
SET @html = '<table id="tablaPrincipal" border=0>
                    <tr style="background:#a7bfde;font-weight:bold;">
                        <td>q1</td>
                        <td>q2</td>
                        <td>Compare</td>
                    </tr>'+
                    (
                        SELECT 
                            isnull(q1,0) AS td
                            ,' ' , isnull(q2,0) AS td
                            ,' ' , name AS td

                    FROM #tempo
                    FOR XML PATH('tr')
                    )
                    +'</TABLE>'        
SELECT @html
DROP TABLE #tempo

我尝试将 td 与另一个标签 tdx 一起使用并像这样替换: SET @html = REPLACE(@html, '', '')

但是,可以根据值动态更改别名吗?

谢谢!

【问题讨论】:

  • 这是表示层的东西。您应该使用 sql 返回数据。然后在前端构建你的 html,包括样式。
  • 我使用这个查询通过一个进程通过电子邮件发送它
  • 明白了。然后你将不得不在每一行添加样式信息。可能需要编写一些 sql 来创建行信息,而不是使用 XML PATH,因为您需要在非常详细的级别上进行控制。
  • 你可能有一个look here

标签: html sql-server xml tsql colors


【解决方案1】:

使用the function mentioned in my comments 你会这样:

这是函数

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 
                <tr> 
                {
                for $th in $first/*
                return <th>{if(not(empty($th/@caption))) then xs:string($th/@caption) else local-name($th)}</th>
                }
                </tr>') AS thead
    ,@tbClass AS [tbody/@class]
    ,@SelectForXmlPathRowElementsXsinil.query(
               N'for $tr in /row
                 return 
                 <tr>{$tr/@class}
                 {
                 for $td in $tr/*
                 return
                 if(empty($td/@link)) 
                 then <td>{$td/@class}{string($td)}</td>
                 else <td>{$td/@class}<a href="{$td/@link}">{string($td)}</a></td>
                 }
                 </tr>') AS tbody
    FOR XML PATH('table'),TYPE
) 
END
GO

--你的测试表

CREATE TABLE #tempo
(
    q1 INT, q2 INT, name VARCHAR(10)
);

INSERT INTO #tempo (q1, q2, name)
VALUES (10, 5, 'low'), (10, 10, 'same'), (10, 20, 'high');
GO

--内联 CSS 便于格式化

DECLARE @inlineCSS XML=
N'<style type="text/css" media="screen,print">
.low
{
    color: black;
    background-color: red;
}
.same
{
    color: black;
    background-color: yellow;
}
.high
{
    color: white;
    background-color: blue;
}
table,th
{
    border: 1px solid black;
}
</style>';

--这是实际的查询

SELECT @inlineCSS 
      ,dbo.CreateHTMLTable
        (
             (
             SELECT 
               CASE WHEN ISNULL(q1,0)>ISNULL(q2,0) THEN 'low' 
                    ELSE CASE WHEN ISNULL(q2,0)>ISNULL(q1,0) THEN 'high' 
                         ELSE 'same' 
                         END 
                    END AS [@class] 
              ,name AS Material
              ,ISNULL(q1,0) AS [Q1]
              ,ISNULL(q2,0) AS [Q2]
             FROM #tempo 
             FOR XML PATH('row'),ELEMENTS XSINIL),NULL,NULL,NULL
        )
FOR XML PATH('body'),ROOT('html');

--提示:使用类名而不是三个,NULL,NULL,NULL 允许将通用CSS 类放置到&lt;table&gt;&lt;thead&gt;&lt;tbody&gt;

--清理

GO
DROP TABLE #tempo
GO
DROP FUNCTION dbo.CreateHTMLTable;

这是结果(点击“运行”查看输出)

<html>
  <body>
    <style type="text/css" media="screen,print">
.low
{
    color: black;
    background-color: red;
}
.same
{
    color: black;
    background-color: yellow;
}
.high
{
    color: white;
    background-color: blue;
}
table,th
{
	border: 1px solid black;
}
</style>
    <table>
      <thead>
        <tr>
          <th>Material</th>
          <th>Q1</th>
          <th>Q2</th>
        </tr>
      </thead>
      <tbody>
        <tr class="low">
          <td>low</td>
          <td>10</td>
          <td>5</td>
        </tr>
        <tr class="same">
          <td>same</td>
          <td>10</td>
          <td>10</td>
        </tr>
        <tr class="high">
          <td>high</td>
          <td>10</td>
          <td>20</td>
        </tr>
      </tbody>
    </table>
  </body>
</html>

【讨论】:

    【解决方案2】:

    这是另一种选择。不清楚您是否只想突出显示一个单元格

    编辑 - 更新为 3 种颜色

    示例

    DECLARE @html varchar(MAX)
    SET @html = '<table id="tablaPrincipal" border=0>
                        <tr style="background:#a7bfde;font-weight:bold;">
                            <td>q1</td>
                            <td>q2</td>
                            <td>Compare</td>
                        </tr>'+
                        (
                        SELECT [td/@style] = 'background:'+choose(sign(q1-q2)+2,'blue;color:white;','yellow','red')
                              ,[td] = isnull(q1,0)
                              ,null
                              ,[td/@style] = 'background:'+choose(sign(q1-q2)+2,'blue;color:white;','yellow','red')
                              ,[td] = isnull(q2,0) 
                              ,null
                              ,[td/@style] = 'background:'+choose(sign(q1-q2)+2,'blue;color:white;','yellow','red')
                              ,[td] = name 
                         FROM #tempo
                        FOR XML PATH('tr')
                        )
                        +'</TABLE>'        
    SELECT @html
    

    退货

    【讨论】:

    • 我认为有一种方法可以将其添加到 xml 中,并且我认为您将是解决这个问题的人。先生再次干得好。
    • @SeanLange 实际上你的解决方案打败了我
    • 我的帖子发布得较早,但您的有一种我不熟悉的使用 FOR XML 的技术。我没有用 xml 做很多实际工作,所以除了基本的构建分隔字符串类型的东西之外,我的印章几乎不存在。
    • @SeanLange 我关注 Snugo ......有人可能会说 :)
    • @Shnugo 请原谅错字。我们都知道我在说谁:)。前段时间我看到了您的链接答案(当时赞成)完全披露...... FLWOR让我头疼。你是对的,我应该说明或至少评论 TR 风格,但我想展示可变 TD 风格,因此我的第一行。
    【解决方案3】:

    这样的事情怎么样。

    CREATE TABLE #tempo(
    q1 INT, q2 INT, name VARCHAR(10)
    )
    
    INSERT INTO #tempo(q1,q2,name)VALUES(10,5,'low')
    INSERT INTO #tempo(q1,q2,name)VALUES(10,10,'same')
    INSERT INTO #tempo(q1,q2,name)VALUES(10,20,'high')
    
    DECLARE @html varchar(MAX) = '<table id="tablaPrincipal" border=0>
                        <tr style="background:#a7bfde;font-weight:bold;">
                            <td>q1</td>
                            <td>q2</td>
                            <td>Compare</td>
                        </tr>'
    
    SELECT @html = @html + '<tr style="background:' + case when q1 < q2 then 'red' when q1 > q2 then 'blue' else 'yellow' end + ';"><td>' + convert(varchar(10), q1) + '</td><td>' + convert(varchar(10), q2) + '</td></tr>'
    FROM #tempo
    
    select @html = @html + '</table>'
    
    select @html
    DROP TABLE #tempo
    

    【讨论】:

    • 通过字符串连接构建 XML(在本例中为 XHTML)总是很危险的...如果所有值都是 int(似乎在这里),这可能没问题,但这在任何情况下,方法都不是最好的...我提供了一个函数here,它将任何SELECT 转换为HTML 表。而且古怪的更新也可能有一些奇怪的副作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    相关资源
    最近更新 更多