使用msdb.dbo.sp_send_dbmail发送HTML附件时开头出现ÿþ乱码求助
解决sp_send_dbmail发送HTML附件开头出现ÿþ字符的问题
问题现象
使用msdb.dbo.sp_send_dbmail发送HTML格式附件时,邮件发送成功,但附件开头会多出ÿþ(对应UTF-8的0xfffe)字符,导致Gmail等邮件客户端无法正常预览:点击附件提示无法预览,双击附件仅显示HTML源码;但将附件保存到本地后,双击可正常打开样式。
用户原始代码:
Declare @html nvarchar(max) Declare @query nvarchar(max) set @html = ' <!DOCTYPE html> <html> <head> <style> table td {border: 1px solid #dddddd;text-align: left;padding: 8px;} th {border: 1px solid #dddddd;text-align: center;padding: 8px;} .main {bgcolor:#3399ff;background:#3399ff;background-color:#3399ff;} .numbrs {text-align: right} </style> </head> <body> <table> <tr><td class="main">Invoice #</td><td>123456</td> <td class="main">Invoice Date</td><td>12/31/2022</td> </table> </html> ' Set @query= 'set nocount on; SELECT ''' + @html + ''' AS Results' EXEC msdb.dbo.sp_send_dbmail @profile_name = 'TEST' ,@recipients = 'name@domain.com' ,@subject = 'Test Email with Attachment' ,@body = 'Please see attached file' ,@body_format ='HTML' ,@Query_no_truncate = 1 ,@Execute_Query_Database='TEST' ,@query =@query ,@query_attachment_filename = 'Report.html' ,@attach_query_result_as_file = 1
异常附件内容示例:
�� <!DOCTYPE html> <html> <head> <style> table td {border: 1px solid #dddddd;text-align: left;padding: 8px;} th {border: 1px solid #dddddd;text-align: center;padding: 8px;} .main {bgcolor:#3399ff;background:#3399ff;background-color:#3399ff;} .numbrs {text-align: right} </style> </head> <body> <table> <tr><td class="main">Invoice #</td><td>123456</td> <td class="main">Invoice Date</td><td>12/31/2022</td> </table> </html>
原因分析
ÿþ是UTF-16LE的字节顺序标记(BOM),由于使用nvarchar(max)(Unicode类型)存储HTML内容,执行查询后返回的Unicode字符串会被sp_send_dbmail以带BOM的格式生成附件,而部分邮件客户端无法正确识别这种编码格式,导致附件解析异常。
解决方案
方案1:改用varchar存储HTML内容
将@html的类型从nvarchar(max)改为varchar(max),查询返回的内容为ASCII/UTF-8编码,不会携带BOM:
Declare @html varchar(max) -- 修改为varchar类型 Declare @query nvarchar(max) set @html = ' <!DOCTYPE html> <html> <head> <style> table td {border: 1px solid #dddddd;text-align: left;padding: 8px;} th {border: 1px solid #dddddd;text-align: center;padding: 8px;} .main {bgcolor:#3399ff;background:#3399ff;background-color:#3399ff;} .numbrs {text-align: right} </style> </head> <body> <table> <tr><td class="main">Invoice #</td><td>123456</td> <td class="main">Invoice Date</td><td>12/31/2022</td> </table> </html> ' Set @query= 'set nocount on; SELECT ''' + @html + ''' AS Results' EXEC msdb.dbo.sp_send_dbmail @profile_name = 'TEST' ,@recipients = 'name@domain.com' ,@subject = 'Test Email with Attachment' ,@body = 'Please see attached file' ,@body_format ='HTML' ,@Query_no_truncate = 1 ,@Execute_Query_Database='TEST' ,@query =@query ,@query_attachment_filename = 'Report.html' ,@attach_query_result_as_file = 1
方案2:在查询中转换为varchar输出
若必须保留nvarchar类型,可在查询语句中将结果转换为varchar(max),去除BOM:
Set @query= 'set nocount on; SELECT CAST(''' + @html + ''' AS varchar(max)) AS Results'
方案3:直接使用本地文件作为附件
如果HTML内容已提前保存到SQL Server可访问的本地路径,直接使用@file_attachment参数代替查询生成附件,彻底避免编码问题:
EXEC msdb.dbo.sp_send_dbmail @profile_name = 'TEST' ,@recipients = 'name@domain.com' ,@subject = 'Test Email with Attachment' ,@body = 'Please see attached file' ,@body_format ='HTML' ,@file_attachment = 'C:\YourPath\Report.html' -- 替换为实际文件路径
内容的提问来源于stack exchange,提问作者BlueTube
相关产品推荐
相关产品推荐

