如何在while循环中保留SQL变量值?

时间:2017-09-04 07:00:29

标签: sql-server tsql stored-procedures

我有以下代码,我希望为每个while循环迭代保留@tableHTML值。哪个我不能。当我在查询下面运行时,我收到一封空邮件。 另外,@ tableHTML可以容纳的最大数据量是多少,因为每个行有10-12个表,每行有20行。由于@tableHTML中的数据溢出而导致空白邮件?

如果我删除@tableHTML赋值,那么我只获取最后一个logID的数据 "设置@tableHTML = @tableHTML +"

CODE:

  DECLARE @tableHTML NVARCHAR(MAX)
  while exists(select * from #temptable)
  begin
    select top 1 @logID = logID
    from #temptable
    Set @tableHTML = @tableHTML +
    N'<H2>Log =' +@logID+'</H2>'+
    N'<H3>List of tests failing in last 24 hours</H3>' +
    N'<table border="1" BORDERCOLOR="#336699" CELLPADDING="2"' +
    N'<tr><th>TestName</th><th>OS</th><th>Branch</th><th>Link</th>
    <th>Failure Rate (%)</th>' +
    N'<th>Failure Count</th><th>Run Count</th></tr>' +
    CAST ( ( SELECT 
                td=TestName, '',
                td=OS, '',
                td=Branch, '',
                td=HTMLLink, '',
                td=FailureRate , '',
                td=FailureCount, '',
                td=TotalRuns, ''
            FROM RepeatedFailingTest 
            WHERE logID = @logID
            GROUP BY 
            TestName,OS,Branch,HTMLLink,FailureRate,
            FailureCount,TotalRuns
            FOR XML PATH('tr'), TYPE
            ) AS NVARCHAR(MAX) ) +
    N'</table>' +
    N'<br><br>'+
    N'</font>';
    delete #temptable
    where logID =@logID
  end
EXEC msdb.dbo.sp_send_dbmail 
@recipients=@myrecipients, 
@body=@tableHTML,
@body_format='HTML', 
@subject=@mysubject,
@profile_name='Log notification system'

1 个答案:

答案 0 :(得分:2)

正如我在评论中提到的, lot 更容易使用任何报告库,包括SQL Server自己的Reporting Services来生成报告并将报告作为电子邮件发送。 SSRS允许您轻松生成分层报告和电子邮件传递订阅。

关于此特定查询,它不需要任何循环。看起来它使用SQL Server的XML支持来生成一个表,如Create HMTML from SQL Queries所示,但随后,恢复为字符串连接以生成外部查询的HTML输出。

XML作为HTML的工作原理是因为每个 XML 查询都返回一个单个 XML值,该值可以是SELECT语句的一部分。这意味着,外部LOG查询可以包括该表。它还意味着每个附加标记都可以包含在SELECT语句中的子查询中。

内部子查询中不需要GROUP BY,因为不会生成聚合。

外部查询应该通过LogID记录,以避免生成重复项。

declare @temptable table (logid integer)

declare @RepeatedFailingTest table (logid int,TestName nvarchar(20),OS nvarchar(20),
                                    Branch nvarchar(20),HTMLLink nvarchar(40),
                                    FailureRate int, FailureCount int ,TotalRuns int)

insert into @temptable values (1),(2)

insert into @RepeatedFailingTest (logid ,TestName ,OS ,Branch ,HTMLLink ,FailureRate , FailureCount ,TotalRuns )
values
(1,'aa','Windows','A1','http://www.google.com',30, 30,100),
(1,'ab','Windows','A1','http://www.google.com',30, 30,100),
(2,'a1','Windows','A1','http://www.google.com',30, 30,100)

select 
    -- Generate H2 here
    (SELECT 'Log = ' + FORMAT(g.logid,'d')  as h2 FOR XML PATH(''), ELEMENTS,TYPE ) ,   
    -- Generate H3 here
    (SELECT 'List of tests failing in last 24 hours' as h3 FOR XML PATH(''), TYPE) ,
    -- Generate the table
    (SELECT     
        --Headings
        (SELECT 'Row' as th, 'TestName' as th , 'OS' as th , 'Branch' as th, 
                'HTMLLink' as th , 'FailureRate' as th, 'FailureCount' as th, 
                'TotalRuns' as th
            FOR XML RAW('tr'), ELEMENTS, TYPE) AS 'thead',
        -- Rows
        (
        SELECT 
          -- Row number
          ROW_NUMBER() OVER(ORDER BY TestName ,OS ,Branch ,HTMLLink ,
                                     FailureRate,FailureCount,TotalRuns)  td,
          TestName as td ,OS as td ,Branch as td,HTMLLink as td ,
          FORMAT(FailureRate,'d') as td,FORMAT(FailureCount,'d') as td,FORMAT(TotalRuns,'d') AS td
          FROM @RepeatedFailingTest f
          where g.logid=f.logid
          ORDER BY TestName ,OS ,Branch ,HTMLLink ,FailureRate,FailureCount,TotalRuns
        FOR XML RAW('tr'), ELEMENTS, TYPE
        ) AS 'tbody'
      FOR XML PATH(''), ROOT('table'),elements, type) 
from @RepeatedFailingTest g
group by g.logid
FOR XML PATH(''), ROOT('body')

要将XML值转换为字符串,可以使用CONVERT将整个结果转换为nvarchar:

select convert(nvarchar(4000),(
select 
    -- Generate H2 here
    (SELECT 'Log = ' + FORMAT(g.logid,'d')  as h2 FOR XML PATH(''), ELEMENTS,TYPE ) ,   
    -- Generate H3 here
    (SELECT 'List of tests failing in last 24 hours' as h3 FOR XML PATH(''), TYPE) ,
    -- Generate the table
    (SELECT     
        --Headings
        (SELECT 'Row' as th, 'TestName' as th , 'OS' as th , 'Branch' as th, 
                'HTMLLink' as th , 'FailureRate' as th, 'FailureCount' as th, 
                'TotalRuns' as th
            FOR XML RAW('tr'), ELEMENTS, TYPE) AS 'thead',
        -- Rows
        (
        SELECT 
          -- Row number
          ROW_NUMBER() OVER(ORDER BY TestName ,OS ,Branch ,HTMLLink ,
                                     FailureRate,FailureCount,TotalRuns)  td,
          TestName as td ,OS as td ,Branch as td,HTMLLink as td ,
          FORMAT(FailureRate,'d') as td,FORMAT(FailureCount,'d') as td,FORMAT(TotalRuns,'d') AS td
          FROM @RepeatedFailingTest f
          where g.logid=f.logid
          ORDER BY TestName ,OS ,Branch ,HTMLLink ,FailureRate,FailureCount,TotalRuns
        FOR XML RAW('tr'), ELEMENTS, TYPE
        ) AS 'tbody'
      FOR XML PATH(''), ROOT('table'),elements, type) 
from @RepeatedFailingTest g
group by g.logid
FOR XML PATH(''), ROOT('body')))

我是否提到使用报告库要容易得多?