如何使用sp_send_dbmail发送包含换行符的纯文本电子邮件?

17

我有一个使用 sp_send_dbmail 发送电子邮件的 SQL Server 2008 存储过程。

我正在使用以下代码:

  set @bodyText = ( select 
                      N'Here is one line of text ' +
                      N'It would be nice to have this on a 2nd line ' +
                      N'Below is some data: ' +
                      N' ' +
                      N' ' +
                      field1 +
                      N' ' +
                      field2 +
                      N' ' +
                      N'This is the last line'
                    from myTable )

    EXEC msdb.dbo.sp_send_dbmail
        @profile_name = 'myProfile',
        @recipients = @to,
        @body = @bodyText,
        @body_format = 'TEXT',
        @subject = 'Testing Email' ;
我的myProfile设置为使用本地smtp服务器,结果会在c:\ inetpub \ mailroot \ queue中生成一个.EML文件。
当我打开其中一个.eml文件时(唉-只有Outlook Express能够打开它们,在其他任何地方查看它们只会显示一个base64编码的blob),它似乎将结果呈现为HTML-因此我不确定问题是否出在客户端上。
我尝试将\n放入消息中,但没有起作用。如何发送具有换行符的纯文本,并验证最终结果是否正确?
顺便说一句,我实际上无法将邮件发送到真正的电子邮件客户端进行测试 - 企业网络受到限制。

这些答案中有没有解决你的问题? - KM.
@KM - 是的。我正在尝试决定接受哪一个 - 你的更优雅,读起来更好,但马丁的也可以。 - chris
4个回答

22

我一直使用 CHAR(13)+CHAR(10) 来创建TSQL中的换行符(它似乎可以与 nvarchar 值混合使用),所以可以尝试像这样:

DECLARE @CRLF char(2)
       ,@bodyText nvarchar(max)
       ,@field1  nvarchar(10)
       ,@field2  nvarchar(10)
SELECT @CRLF=CHAR(13)+CHAR(10)
      ,@field1='your data'
      ,@field2='and more'

set @bodyText =
                N'Here is one line of text ' 
                +@CRLF+ N'It would be nice to have this on a 2nd line ' 
                +@CRLF+ N'Below is some data: ' + N' ' + N' ' + ISNULL(@field1,'') + N' ' + ISNULL(@field2 + N' ' ,'')
                +@CRLF+ N'This is the last line' 


PRINT @bodyText

输出:

Here is one line of text 
It would be nice to have this on a 2nd line 
Below is some data:   your data and more 
This is the last line

这个 CHAR(13)+CHAR(10) 在使用 msdb.dbo.sp_send_dbmail 时有效,我经常使用它来发送格式化的电子邮件。


2
如果您发送的电子邮件正文是HTML格式,则不需要这样做。 - Fandango68

9

实际上您并没有插入任何换行符。您可以像以下代码一样直接在 SQL Server 中嵌入字符串字面量中的换行符。

SET @bodyText = (SELECT N'Here is one line of text 
It would be nice to have this on a 2nd line 
Below is some data: 


' + field1 + N' 

' + field2 + N' 

' + N'This is the last line'
                 FROM   myTable);

或者更整洁的方法可能是:
DECLARE @Template NVARCHAR(max) = 
N'Here is one line of text 
It would be nice to have this on a 2nd line 
Below is some data: 

##field1##

##field2##

This is the last line';

SET @bodyText = (SELECT REPLACE(
                    REPLACE(@Template, 
                       '##field1##', field1), 
                       '##field2##', field2)
                 FROM   myTable); 

如果您将结果分配给标量变量,那么如果myTable包含多行数据,两者都会引发错误。


令人惊讶的是,它确实可以!事实上,我可以将整个代码块放入一对引号中。 - chris
这真的让代码看起来很怪异,我曾经也是那样做。然而,我发现使用CHAR(13)+CHAR(10)对于查询和其他代码的缩进效果更好。 - KM.
是的,它在缩进方面的效果并不是很好,因为 ' 需要放在行的开头才能避免注入大量多余的空格,但在不需要考虑这个问题的情况下,它看起来更像所见即所得。 - Martin Smith

7

正如Fernando68上面提到的,如果你允许使用HTML电子邮件,请设置@body_format = 'HTML',然后您可以使用<br/>进行换行,并使用所有从HTML获取的标签使其变得更加漂亮,例如换行、img、strong等...

set @bodyText = ( select 
                  '<h1>My Data</h1><p>Here is one line of text<br/>
                   It would be nice to have this on a 2nd line <br/>
                   Below is some data: <br/>'
                   + field1 + '<br/>'
                   + field2 + '<br/>'
                   + 'This is the last line</p>'
                   from myTable )

EXEC msdb.dbo.sp_send_dbmail
    @profile_name = 'myProfile',
    @recipients = @to,
    @body = @bodyText,
    @body_format = 'HTML',
    @subject = 'Testing Email' ;

这并不是真正回答原问题,但可能是最好和最简单的解决方案。我过去使用过这种方法来可靠地解决这个问题(我找到了一个通常有效但不总是有效的文本解决方案!)。 - Zeek2

1
在我的情况下,带有CHAR(13)+CHAR(10)的纯文本电子邮件会被Outlook格式化,这是因为Outlook会“贴心地”删除额外的换行符(除非在Outlook选项中取消勾选)。
此外,我的条目列表将是动态的,因此我编写了STUFF FOR XML PATH,它可以提取连接字符串并简单地添加一个空字符串和一个新的换行符,然后将其分配给sp_send_dbmail的@body = @emailBody。
DECLARE @emailBody VARCHAR(MAX)

SET @emailBody = CONCAT('files: '
    ,(SELECT STUFF((SELECT
    ' 

' + CONCAT([FileName],'.csv')
    FROM localdb.dbo.tableName
    for xml path(''), TYPE).value('.', 'VARCHAR(MAX)'),1,1,'')))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接