Writing HTML out from a stored procedure and emailing it
sql, sql-server, t-sql
Solution
All of the usual stuff about that being a bad practice aside, what your ex-coworker seems to be doing is leveraging SQL Server's native XML capabilities. You are not getting the "td" tags because they are not being assigned in your sub-query.
If you look at his queries, you will see the "td = ..." constructs. The reason they work is because the sub-query is being treated as XML (due to the `FOR XML PATH` construct) and thus the "td = " clauses are being mapped to XML nodes.
Try adding that to your code and see if you get the proper table cells...
BEGIN
DECLARE @tableHTML NVARCHAR(MAX) ;
SET @tableHTML =
N'<b>Shots Statistics for ' + convert(varchar, GETDATE()-1, 101) + ':</b>' +
N'<table border="1" width="400">' +
CAST (
(SELECT td = 'Practice:' + PracticeName as Status, 'Aprima ID:'+ AprimaSiteID,
td = 'Daily Count:' + CAST(Daily AS nvarchar(5)), 'Monthly Count:' + CAST(Monthly AS nvarchar(5))
FROM [CriticalKeyDatabase].[dbo].[ShotsManagement]
ORDER BY Status
FOR XML PATH('tr'), TYPE
) AS NVARCHAR(MAX) ) +
N'</table>';
exec msdb.dbo.sp_send_dbmail @profile_name='aProfileName', @recipients='anEmail@Email.com', @body=@tableHTML, @subject='Daily Shots', @importance='High', @body_format = 'HTML'
END
GO
Problem
My boss insists I send him a daily status report "the hacker way" by outputing HTML from a stored procedure and sending the return to his email using Database mailer. My colleague and I both agree that we should be using SSRS for this matter but since we aren't the ones with the money we unfortunately have to get stuck doing it this way. I myself have never seen this done and am having some formatting issues getting my table to format with cells. Can anyone shed some light on how to get this to work? ``` BEGIN DECLARE @tableHTML NVARCHAR(MAX) ; SET @tableHTML = N'<b>Shots Statistics for ' + convert(varchar, GETDATE()-1, 101) + ':</b>' + N'<table border="1" width="400">' + CAST ( (SELECT 'Practice:' + PracticeName as Status, 'Aprima ID:'+ AprimaSiteID, 'Daily Count:' + CAST(Daily AS nvarchar(5)), 'Monthly Count:' + CAST(Monthly AS nvarchar(5)) FROM [CriticalKeyDatabase].[dbo].[ShotsManagement] ORDER BY Status FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>'; exec msdb.dbo.sp_send_dbmail @profile_name='aProfileName', @recipients='anEmail@Email.com', @body=@tableHTML, @subject='Daily Shots', @importance='High', @body_format = 'HTML' END GO ``` I am basing this off a previous employee he had who gave him the idea. I don't see any declarations for cells anywhere in his query. I am not the best at SQL either.. ``` DECLARE @tableHTML NVARCHAR(MAX) ; SET @tableHTML = N'<b>Message Statistics for ' + convert(varchar, GETDATE()-1, 101) + ':</b>' + N'<table border="1" width="400">' + CAST ( ( SELECT td = Status, ' ', td = convert(varchar, StatusValue) + '', ' ' FROM (SELECT 'Unsent Messages' as Status, Count(*) as StatusValue FROM [CriticalKeyDatabase].[dbo].[AllJobs_V] where convert(varchar, CreateDate, 101) = convert(varchar, GETDATE()-1, 101) and ReadyToSend = 1 UNION SELECT 'Total Messages' as Status, Count(*) as StatusValue FROM [CriticalKeyDatabase].[dbo].[AllJobs_V] where convert(varchar, CreateDate, 101) = convert(varchar, GETDATE()-1, 101)) A ORDER BY StatusValue FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>' + N'<b>Sender Statistics for ' + convert(varchar, GETDATE()-1, 101) + ':</b>' + N'<table border="1" width="400">' + CAST ( ( SELECT td = Status, ' ', td = convert(varchar, StatusValue) + '', ' ' FROM (SELECT 'Sender: ' + Requestor as Status, Count(*) as StatusValue FROM [CriticalKeyDatabase].[dbo].[AllJobs_V] where convert(varchar, CreateDate, 101) = convert(varchar, GETDATE()-1, 101) group by Requestor) A ORDER BY Status FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>' + N'<b>Recipient Statistics for ' + convert(varchar, GETDATE()-1, 101) + ':</b>' + N'<table border="1" width="400">' + CAST ( ( SELECT td = Status, ' ', td = convert(varchar, StatusValue) + '', ' ' FROM (SELECT 'Recipient: ' + Recipient as Status, Count(*) as StatusValue FROM [CriticalKeyDatabase].[dbo].[AllJobs_V] where convert(varchar, CreateDate, 101) = convert(varchar, GETDATE()-1, 101) group by Recipient) A ORDER BY Status FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>' + N'<b>Event Statistics for ' + convert(varchar, GETDATE()-1, 101) + ':</b>' + N'<table border="1" width="400">' + CAST ( ( SELECT td = Status, ' ', td = convert(varchar, StatusValue) + '', ' ' FROM (SELECT 'Event: ' + EventType as Status, Count(*) as StatusValue FROM [CriticalKeyDatabase].[dbo].[AllJobs_V] where convert(varchar, CreateDate, 101) = convert(varchar, GETDATE()-1, 101) group by EventType) A ORDER BY Status FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>'; exec msdb.dbo.sp_send_dbmail @profile_name='Localhost', @recipients='someemailAddresses@email.com', @body=@tableHTML, @subject='Daily Statistics', @importance='High', @body_format = 'HTML' END ``` The previous employee's reports looked like this. But mine are coming out like this.