Fala pessoal!!
Neste post eu venho trazer uma solução para um problema que quase todos os dias eu vejo nos grupos de Whatsapp e Telegram: Enviar o conteúdo de uma ou mais tabelas ou queries no corpo de um e-mail como HTML.
A procedure que vamos utilizar nesse post para pegar o conteúdo da tabela e transformar para HTML eu já havia compartilhado no artigo Como exportar dados de uma tabela do SQL Server para HTML, mas vejo que sempre que enviava o artigo, as pessoas ainda tinham dificuldade de enviar o e-mail, então resolvi criar esse artigo para sanar essa dúvida de uma vez por todas.
Se você não sabe como configurar o Database Mail para começar a enviar e-mails pelo SQL Server ou está com dificuldades em enviar e-mails simples, acesse o artigo SQL Server – Como ativar e configurar o Database mail para enviar e monitorar e-mails pelo banco de dados (sp_send_dbmail).
Utilizando a própria sp_send_dbmail e o parâmetro @query
Provavelmente, uma das formas mais utilizadas para enviar o resultado de uma tabela por e-mail é utilizando o parâmetro @query da sp_send_dbmail.
Exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
EXEC msdb.dbo.sp_send_dbmail @profile_name = 'ProfileEnvioEmail', -- sysname @subject = N'Teste', -- nvarchar(255) @body = N'Teste', -- nvarchar(max) @body_format = 'html', -- Parâmetros específicos do envio da query @query = N'select top 20 * from [dirceuresende].[dbo].[Clientes]', -- nvarchar(max) @query_result_header = 1, -- bit @exclude_query_output = 1, -- bit @query_result_width = 50, -- int @query_result_separator = '|' -- char(1) |
Como vocês podem perceber, embora seja extremamente simples de se utilizar, o resultado é bem ruim para visualização dos dados..
Utilizando a própria sp_send_dbmail e o parâmetro @attach_query_result_as_file
Vou tentar enviando esse conteúdo como anexo para ver se melhora. Talvez exportando pra arquivo, a saíde fique um pouco melhor..
Exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
EXEC msdb.dbo.sp_send_dbmail @profile_name = 'ProfileEnvioEmail', -- sysname @subject = N'Teste', -- nvarchar(255) @body = N'Teste', -- nvarchar(max) @body_format = 'html', -- Parâmetros específicos do envio da query @query = N'select top 20 * from [dirceuresende].[dbo].[Clientes]', -- nvarchar(max) @query_result_header = 1, -- bit @exclude_query_output = 1, -- bit @query_result_width = 50, -- int @query_result_separator = '|', -- char(1) -- Transformando em arquivo @attach_query_result_as_file = 1, @query_attachment_filename = 'arquivo.txt' |
Mais um resultado bem ruim… Não melhorou muito.
Utilizando XML para criar uma variável com o resultado em HTML
Vamos utilizar outra abordagem então para tentar exportar os dados da tabela e enviar em um e-mail de forma que fique fácil de visualizar os dados.
Exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
-- Transforma o conteúdo da query em HTML DECLARE @HTML VARCHAR(MAX); SET @HTML = ' <table border="1"> <tr> <th>Codigo</th> <th>Nome</th> <th>Ativo?</th> </tr>' + CAST ( ( SELECT TOP 20 td = Codigo, '', td = Nome, '', td = Ativo FROM [dirceuresende].[dbo].[Clientes] FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + ' </table>'; -- Envia o e-mail EXEC msdb.dbo.sp_send_dbmail @profile_name = 'ProfileEnvioEmail', -- sysname @subject = N'Teste', -- nvarchar(255) @body = @HTML, -- nvarchar(max) @body_format = 'html' |
Opa!! Já tá ficando bem melhor! Agora vou personalizar um pouco só pra mostrar a vocês que dá pra brincar com o design das mensagens.
Exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
-- Transforma o conteúdo da query em HTML DECLARE @HTML VARCHAR(MAX); SET @HTML = ' <html> <head> <title>Titulo</title> <style type="text/css"> table { padding:0; border-spacing: 0; border-collapse: collapse; } thead { background: #00B050; border: 1px solid #ddd; } th { padding: 10px; font-weight: bold; border: 1px solid #000; color: #fff; } tr { padding: 0; } td { padding: 5px; border: 1px solid #cacaca; margin:0; text-align: center; } </style> </head> <h2>Lista de Usuários do Sistema</h2> Veja a lista dos usuários permitidos no sistema:<br/><br/> <table> <thead> <tr> <th>Codigo</th> <th>Nome</th> <th>Ativo?</th> </tr> </thead> <tbody>' + CAST ( ( SELECT TOP 20 td = Codigo, '', td = Nome, '', td = Ativo FROM [dirceuresende].[dbo].[Clientes] FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + ' </tbody> </table> <br/><br/> Em caso de dúvidas, favor entrar em contato<br/><br/> Atenciosamente,<br/> <img src="https://www.sqlsaturday.com/images/speakers/6984-e5594a7e.jpg" /><br/> DBA'; -- Envia o e-mail EXEC msdb.dbo.sp_send_dbmail @profile_name = 'ProfileEnvioEmail', -- sysname @subject = N'Teste', -- nvarchar(255) @body = @HTML, -- nvarchar(max) @body_format = 'html' |
Tá ficando bem maneiro esse e-mail, hein?? E se eu quiser enviar mais de uma tabela no mesmo e-mail? Tem como???
Exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
-- Transforma o conteúdo da query em HTML DECLARE @HTML VARCHAR(MAX); SET @HTML = ' <html> <head> <title>Titulo</title> <style type="text/css"> table { padding:0; border-spacing: 0; border-collapse: collapse; } thead { background: #00B050; border: 1px solid #ddd; } th { padding: 10px; font-weight: bold; border: 1px solid #000; color: #fff; } tr { padding: 0; } td { padding: 5px; border: 1px solid #cacaca; margin:0; text-align: center; } </style> </head> <h2>Lista de Usuários do Sistema</h2> Veja a lista dos usuários permitidos no sistema:<br/><br/> <table> <thead> <tr> <th>Codigo</th> <th>Nome</th> <th>Ativo?</th> </tr> </thead> <tbody>' + CAST ( ( SELECT TOP 20 td = Codigo, '', td = Nome, '', td = Ativo FROM [dirceuresende].[dbo].[Clientes] FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + ' </tbody> </table> <br/><br/> <h2>Lista de dos Objetos no Banco</h2> Veja a lista dos objetos que existem nesse banco:<br/><br/> <table> <thead> <tr> <th>Nome</th> <th>ID do Objeto</th> <th>Data de Criação</th> <th>Objeto de Sistema?</th> <th>Lock Escalation</th> <th>Durability</th> <th>Temporal Type</th> </tr> </thead> <tbody>' + CAST ( ( SELECT TOP 20 td = [name] , '', td = [object_id], '', td = CONVERT(VARCHAR(19), create_date, 103), '', td = (CASE WHEN is_ms_shipped = 1 THEN 'true' ELSE 'false' END), '', td = lock_escalation_desc, '', td = durability_desc, '', td = temporal_type_desc FROM dirceuresende.sys.tables FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + ' </tbody> </table> <br/><br/> Em caso de dúvidas, favor entrar em contato<br/><br/> Atenciosamente,<br/> <img src="https://www.sqlsaturday.com/images/speakers/6984-e5594a7e.jpg" /><br/> DBA'; -- Envia o e-mail EXEC msdb.dbo.sp_send_dbmail @profile_name = 'ProfileEnvioEmail', -- sysname @subject = N'Teste', -- nvarchar(255) @body = @HTML, -- nvarchar(max) @body_format = 'html' |
Modo Easy: stpExporta_Tabela_HTML_Output
Pensando em facilitar o envio do conteúdo de uma tabela ou query por e-mail como HTML, resolvi criar a Stored Procedure stpExporta_Tabela_HTML_Output para automatizar a transformação do resultado de uma tabela ou query para HTML e poder usar isso para criar um arquivo ou enviar o HTML gerado como o corpo de um e-mail.
Essa procedure já havia sido compartilhada no artigo Como exportar dados de uma tabela do SQL Server para HTML, mas resolvi compartilhar de novo aqui, com foco em envio de e-mail HTML.
Código da stpExporta_Tabela_HTML_Output:
Clique aqui para visualizar o código-fonte
O seu uso é bem simples:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
-- Transforma o conteúdo da query em HTML DECLARE @HTML VARCHAR(MAX) EXEC dbo.stpExporta_Tabela_HTML_Output @Ds_Tabela = 'dirceuresende.dbo.Clientes', -- varchar(max) @Ds_Saida = @HTML OUTPUT -- varchar(max) -- Envia o e-mail EXEC msdb.dbo.sp_send_dbmail @profile_name = 'ProfileEnvioEmail', -- sysname @subject = N'Teste', -- nvarchar(255) @body = @HTML, -- nvarchar(max) @body_format = 'html' |
Caso eu queira trocar o alinhamento horizontal, basta utilizar o parâmetro @Ds_Alinhamento:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
-- Transforma o conteúdo da query em HTML DECLARE @HTML VARCHAR(MAX) EXEC dbo.stpExporta_Tabela_HTML_Output @Ds_Tabela = 'dirceuresende.dbo.Clientes', -- varchar(max) @Ds_Saida = @HTML OUTPUT, -- varchar(max) @Ds_Alinhamento = 'center' -- parâmetros: left, center e right -- Envia o e-mail EXEC msdb.dbo.sp_send_dbmail @profile_name = 'ProfileEnvioEmail', -- sysname @subject = N'Teste', -- nvarchar(255) @body = @HTML, -- nvarchar(max) @body_format = 'html' |
Caso você queira utilizar o resultado de uma query ao invés do conteúdo de uma tabela inteira, basta utilizar uma tabela temporária global (##tabela), pois a temporária local (#tabela) não irá funcionar:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
-- Cria uma nova tabela com o resultado da query desejada IF (OBJECT_ID('tempdb..##Teste') IS NOT NULL) DROP TABLE ##Teste SELECT Codigo, Nome INTO ##Teste FROM dirceuresende.dbo.Clientes WHERE Codigo > 2 -- Transforma o conteúdo da query em HTML DECLARE @HTML VARCHAR(MAX) EXEC dbo.stpExporta_Tabela_HTML_Output @Ds_Tabela = '##Teste', -- varchar(max) @Ds_Saida = @HTML OUTPUT -- varchar(max) |
E para enviar o mesmo e-mail do exemplo utilizando o XML, ficaria assim:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
DECLARE @HTML VARCHAR(MAX), @HTML1 VARCHAR(MAX), @HTML2 VARCHAR(MAX) -- Transforma o conteúdo da query em HTML EXEC dbo.stpExporta_Tabela_HTML_Output @Ds_Tabela = 'dirceuresende.dbo.Clientes', -- varchar(max) @Ds_Saida = @HTML1 OUTPUT -- varchar(max) IF (OBJECT_ID('tempdb..##Tabela2') IS NOT NULL) DROP TABLE ##Tabela2 SELECT TOP 20 [name], [object_id], CONVERT(VARCHAR(19), create_date, 103) AS create_date, (CASE WHEN is_ms_shipped = 1 THEN 'true' ELSE 'false' END) AS is_ms_shipped, lock_escalation_desc, durability_desc, temporal_type_desc INTO ##Tabela2 FROM dirceuresende.sys.tables EXEC dbo.stpExporta_Tabela_HTML_Output @Ds_Tabela = '##Tabela2', -- varchar(max) @Ds_Saida = @HTML2 OUTPUT, -- varchar(max) @Fl_Aplica_Estilo_Padrao = 0 -- Utilizar 0 se for utilizar a Procedure mais de 1x SET @HTML = ' <h2>Lista de Usuários do Sistema</h2> Veja a lista dos usuários permitidos no sistema:<br/><br/>' + ISNULL(@HTML1, '') + ' <br/><br/> <h2>Lista de dos Objetos no Banco</h2> Veja a lista dos objetos que existem nesse banco:<br/><br/>' + ISNULL(@HTML2, '') + ' <br/><br/> Em caso de dúvidas, favor entrar em contato<br/><br/> Atenciosamente,<br/> <img src="https://www.sqlsaturday.com/images/speakers/6984-e5594a7e.jpg" /><br/> DBA'; -- Envia o e-mail EXEC msdb.dbo.sp_send_dbmail @profile_name = 'ProfileEnvioEmail', -- sysname @subject = N'Teste', -- nvarchar(255) @body = @HTML, -- nvarchar(max) @body_format = 'html' |
E é isso aí, pessoal!
Espero que tenham gostado dessa dica e até o próximo post.
consigo transformar em csv e enviar anexado?
Obrigado Pelo Material!
Tenho como realizar um alinhamento coluna por coluna?
Abrs.
Valeu Dirceu. Muito obrigado.
Show, agora manda um para gerar um arquivo pdf
rsrs boa.