Reputation: 341
The Story: We have a requirement to send periodic requests to customer requesting they re-certify thier profiles that are in our system. Curently this in a manual process but we have dscided to automate it by using SQL Server's email capabilites.
My solution: I'm curently working on the body of the email which will then be emailed to the customer. Required in the body are the contact information and a table with each process that needs to be recertified.
The problem: The difficulty I am encountering is that, even though I'm moving (it looks like) from top to bottom, the HTML email body I've developed is not formatting properly and I can't tell why not.
Here is my SQL code
WITH htmlresult AS (
SELECT
''AS RowNumber
,'<html><head><title></title></head>
<body> <BR>' AS HtmlData
UNION ALL
select top 1
''AS RowNumber
, 'Date: ' + CAST(GETDATE() AS VARCHAR(12)) + '<BR><BR> ' +
'Re: Annual Re-certification Information Profiles' + '<BR><BR> ' +
'Contact Name: ' + dbo.DueTempTbl.[Contact] + '
Email: ' + dbo.DueTempTbl.[EMAIL] + ' <BR>' +
'GenName: ' + dbo.DueTempTbl.[GenName]+ '<BR> ' +
'GenNumber: ' + dbo.DueTempTbl.[Gen#] + '<BR><BR> ' AS
HtmlData
FROM dbo.DueTempTbl
WHERE [RECERTDUE] Between DATEADD(DAY, -180, GETDATE()) And DATEADD(DAY,
+60, GETDATE())
AND ((dbo.DueTempTbl.[Terr])='AZ1') AND ((LTrim(RTrim([EMAIL])))<>'')
AND [Gen#]=623113
UNION ALL
SELECT
'' AS RowNumber
, 'The annual re-certification of your information profiles are due for
those expiring <BR> in the next ninety (90) days. ' +
'It is necessary to complete this re-certification in advance to ensure no
<BR> interruption of future service. <br><br>' AS HtmlData
union all
SELECT '' AS RowNumber
,' <br><br><table><tr style="background-color: #5D7B9D; font-weight: bold;
color: white;">
<td>ID Number</td><td>Description</td><td>Recert Due Date</td></tr>' AS
HtmlData
Union All
SELECT ROW_NUMBER() OVER (ORDER BY [IDNumber]) AS RowNumber
,'<td>' + CAST([IDNumber] as VARCHAR(10)) + '</td><td>' + RTrim([WasteName])
+ '</td>' +
'<td>' + CAST([RECERTDUE]as VARCHAR(12)) + '</td>' AS HtmlData
FROM dbo.DueTempTbl
WHERE [RECERTDUE] Between DATEADD(DAY, -180, GETDATE()) And DATEADD(DAY,
+60, GETDATE())
AND [Gen#]=623113
SELECT HtmlData =
CASE RowNumber%2
WHEN 0 THEN '<tr style="background-color: #F7F6F3">' + HtmlData +
'</tr>'
ELSE '<tr>' + HtmlData + '</tr>'
END
FROM htmlresult
UNION ALL
SELECT '</table><BR><BR> Thank you for allowing us to provide you with
reliable and safe service. <BR> ' +
'We strive for excellence in providing these services and we hope
that this has been your <BR> experience ' +
'with us.</body></html>'
Here is the output I was expecting
<html>
<head>
<title></title>
</head>
<body>
<BR>Date: Sep 7 2018
<BR><BR> Re: Annual Re-certification of Information Profiles
<BR><BR> Contact Name: Paul Bunyan Email:
[email protected]
<BR>Gen Name: Some Company
<BR>Gen Number: 623113<BR><BR>
<table>
<tr style="background-color: #F7F6F3">The annual re-certification of your
Information Profiles are due for those expiring <BR> in the next ninety (90)
days. It is necessary to complete this process in advance to ensure no <BR>
interruption of service. <br><br></tr>
<tr style="background-color: #F7F6F3"> <br><br><table><tr style="background-
color: #5D7B9D; font-weight: bold; color: white;">
<td>IDNumber</td><td>Decription</td><td>Recert Due Date</td></tr></tr>
<tr><td>780877</td><td>quas vidit docendi pro</td><td>Sep 13 2018 </td></tr>
<tr style="background-color: #F7F6F3"><td>780878</td><td>Lorem ipsum
dolor</td><td>Sep 13 2018 </td></tr>
<tr><td>780879</td><td>sit amet</td><td>Sep 13 2018 </td></tr>
<tr style="background-color: #F7F6F3"><td>780880</td><td>uisset eligendi
ius</td><td>Sep 13 2018 </td></tr>
<tr><td>780881</td><td>vix illum commune</td><td>Sep 13 2018 </td></tr>
<tr style="background-color: #F7F6F3"><td>780882</td><td>mea omnesque
liberavisse</td><td>Sep 13 2018 </td></tr>
<tr><td>780883</td><td>suscipiantur cu</td><td>Sep 13 2018 </td></tr>
<tr style="background-color: #F7F6F3"><td>780884</td><td>cam appareat mei
ut</td><td>Sep 13 2018 </td></tr>
<tr><td>780885</td><td>sit maiorum repudiare</td><td>Sep 13 2018 </td></tr>
<tr style="background-color: #F7F6F3"><td>780886</td><td>olum dicat
fabellas</td><td>Sep 13 2018 </td></tr>
<tr><td>780937</td><td>vidit docendi pro</td><td>Sep 13 2018 </td></tr>
</table><BR><BR>
Thank you for allowing us to provide you with reliable and safe services. We
strive for excellence in providing these services and we hope that this has
been your
<BR> experience with us.
</body></html>
And here is what I got
<tr style="background-color: #F7F6F3">
<html>
<head>
<title></title>
</head>
<body>
<BR>Date: Sep 7 2018
<BR><BR> Re: Annual Re-certification of Information Profiles
<BR><BR> Contact Name: Paul Bunyan Email:
[email protected]
<BR>Gen Name: Some Company
<BR>Gen Number: 623113<BR><BR>
<BR>Date: Sep 7 2018
<BR><BR> Re: Annual Re-certification of Information Profiles
<BR><BR> Contact Name: Paul Bunyan Email:
[email protected]
<BR>Gen Name: Some Company
<BR>Gen Number: 623113<BR><BR>
<tr style="background-color: #F7F6F3">The annual re-certification of your
Information Profiles are due for those expiring
<BR> in the next ninety (90) days. It is necessary to complete this process
in advance to ensure no <BR> interruption of service. <br><br></tr>
<tr style="background-color: #F7F6F3"> <br><br><table><tr style="background-
color: #5D7B9D; font-weight: bold; color: white;">
<td>IDNumber</td><td>Decription</td><td>Recert Due Date</td></tr></tr>
<tr><td>780877</td><td>quas vidit docendi pro</td><td>Sep 13 2018 </td></tr>
<tr style="background-color: #F7F6F3"><td>780878</td><td>Lorem ipsum
dolor</td><td>Sep 13 2018 </td></tr>
<tr><td>780879</td><td>sit amet</td><td>Sep 13 2018 </td></tr>
<tr style="background-color: #F7F6F3"><td>780880</td><td>uisset eligendi
ius</td><td>Sep 13 2018 </td></tr>
<tr><td>780881</td><td>vix illum commune</td><td>Sep 13 2018 </td></tr>
<tr style="background-color: #F7F6F3"><td>780882</td><td>mea omnesque
liberavisse</td><td>Sep 13 2018 </td></tr>
<tr><td>780883</td><td>suscipiantur cu</td><td>Sep 13 2018 </td></tr>
<tr style="background-color: #F7F6F3"><td>780884</td><td>cam appareat mei
ut</td><td>Sep 13 2018 </td></tr>
<tr><td>780885</td><td>sit maiorum repudiare</td><td>Sep 13 2018 </td></tr>
<tr style="background-color: #F7F6F3"><td>780886</td><td>olum dicat
fabellas</td><td>Sep 13 2018 </td></tr>
<tr><td>780937</td><td>vidit docendi pro</td><td>Sep 13 2018 </td></tr>
</table><BR><BR> Thank you for allowing us to provide you with reliable and
safe services. We strive for excellence in providing these services and we
hope that this has been your <BR> experience with us.</body></html>
(SQL Server 2008R2)
By the way, I really should give credit to Steve Moore, the source I used in development of this code. http://www.sqlservercentral.com/articles/T-SQL/99398/
Upvotes: 2
Views: 546
Reputation: 341
Ok, XML worked! Here is the final code that I used and it is producing well formated HTML.
Declare @Body varchar(max),
@TableHead varchar(max),
@TableTail varchar(max),
@Message1 varchar (max),
@Message2 varchar (max),
@genNum as integer,
@HTMLHead as varchar(max),
@TableBody varchar(max)
SET @genNum = 623113
Set NoCount On;
SELECT TOP 1 @Message1 ='Date: ' + CAST(GETDATE() AS VARCHAR(12)) + '<BR><BR> ' +
'Re: Annual Re-certification of Information Profiles' + '<BR><BR> ' +
'Contact Name: ' + dbo.TblRecertsDueTemp.[Contact] + ' Email: ' +
dbo.TblRecertsDueTemp.[EMAIL] + ' <BR> ' +
'Generator Name: ' + dbo.TblRecertsDueTemp.[GenName]+ '<BR> ' +
'Generator Number: ' + dbo.TblRecertsDueTemp.[Gen#] + '<BR><BR> '
FROM dbo.TblRecertsDueTemp
WHERE DBO.FN_ChangeToDate([RECERTDUE]) Between DATEADD(DAY, -180, GETDATE()) And DATEADD(DAY, +60, GETDATE())
AND [Gen#]=@genNum;
SET @Message2 = @Message1 + '<table style="width:533px;border-collapse: collapse; border: none;"> <tr><td>The annual re-certification of your Information Profiles are due for those expiring in the next ninety (90) days. It is necessary to complete this process in advance to ensure no interruption of future services. We have a <a href="url">simple Web form</a> for you to use to complete this process. <a href="url">Click here</a> to see directions on how to complete these recertifications. </td></tr> </table> <BR><BR> '
Set @HTMLHead = '<!DOCTYPE html> <html><head>' +
'<style>' +
'td {border: solid black 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font-size:11pt;} ' +
'</style>' +
'</head>' +
'<body>'
Set @TableHead = '<table cellpadding=0 cellspacing=0 border=0>' +
'<tr style="background-color: #5D7B9D; font-weight: bold; color: white;">' +
' <td>WIP</td>'+
' <td>Decription</td>'+
' <td>Recert Due Date</td>'+
'</tr>'
Set @TableTail = '</table></body></html>';
Select @TableBody = (SELECT ROW_NUMBER() OVER (ORDER BY [WIP]) % 2 As [TRRow],
CAST([IP] AS VARCHAR(10)) + ' ' As [TD],
RTrim([ProcessName]) As [TD],
CONVERT(varchar,DBO.FN_ChangeToDate([RECERTDUE]),101) As [TD]
FROM dbo.TblRecertsDueTemp
WHERE DBO.FN_ChangeToDate([RECERTDUE]) Between DATEADD(DAY, -180, GETDATE()) And DATEADD(DAY, +60, GETDATE())
AND [Gen#]=@genNum
For XML raw('tr'), Elements)
-- Replace the entity codes and row numbers
Set @TableBody = Replace(@TableBody, '_x0020_', space(1))
Set @TableBody = Replace(@TableBody, '_x003D_', '=')
Set @TableBody = Replace(@TableBody, '<tr><TRRow>1</TRRow>', '<tr bgcolor=#C6CDDD>')
Set @TableBody = Replace(@TableBody, '<TRRow>0</TRRow>', '')
Select @Body = @HTMLHead+ @Message2 + @TableHead + @TableBody + @TableTail
-- return output
Select @Body
(Developed with the help of Robert Davis- http://www.sqlservercentral.com/blogs/robert_davis/2010/06/15/Building-HTML-Emails-With-SQL-Server-and-XML/)
Upvotes: 0
Reputation: 4715
Assuming you're talking about that chunk of mising values
10. [email protected]
10. <BR>Gen Name: Some Company 11. <BR>Gen Name: Some Company
12. <BR>Gen Number: 623113<BR><BR>
13. <BR>Date: Sep 7 2018
14. <BR><BR> Re: Annual Re-certification of Information Profiles
15. <BR><BR> Contact Name: Paul Bunyan Email:
16. [email protected]
17. <BR>Gen Name: Some Company
it's probably because this section of code is not returning any data
select top 1
''AS RowNumber
, 'Date: ' + CAST(GETDATE() AS VARCHAR(12)) + '<BR><BR> ' +
'Re: Annual Re-certification Information Profiles' + '<BR><BR> ' +
'Contact Name: ' + dbo.DueTempTbl.[Contact] + '
Email: ' + dbo.DueTempTbl.[EMAIL] + ' <BR>' +
'GenName: ' + dbo.DueTempTbl.[GenName]+ '<BR> ' +
'GenNumber: ' + dbo.DueTempTbl.[Gen#] + '<BR><BR> ' AS
HtmlData
FROM dbo.DueTempTbl
WHERE [RECERTDUE] Between DATEADD(DAY, -180, GETDATE()) And DATEADD(DAY,
+60, GETDATE())
AND ((dbo.DueTempTbl.[Terr])='AZ1') AND ((LTrim(RTrim([EMAIL])))<>'')
AND [Gen#]=623113
I'd strongly recommend against writing HTML in SQL, but if you must, I would further discourage you from using string concatenation in favor of XML manipulation (which HTML is basically a subset)
Upvotes: 1