我们使用sp_send_dbmail通知我们某些问题,有时我们会将文件附加到电子邮件中。偶尔我们会收到错误32(正在使用的文件)错误。在这种情况下,我已经将一些代码放在一起发送没有附件的电子邮件,但无论我做什么,我都无法捕获错误并忽略它。
我希望能够处理或忽略sp_send_dbmail中的任何错误,因为这会导致生产中的作业失败。
我尝试实现本文http://www.sqlusa.com/articles2008/trycatch/中描述的技术,如下所示:
CREATE PROC dbo.sp_send_email
(
@recipients VARCHAR(100),
@body VARCHAR(max),
@subject VARCHAR(100),
@file_attachments VARCHAR(100)=''
)
AS
BEGIN
DECLARE @retcode INT
BEGIN TRY
EXEC @retcode = msdb.dbo.sp_send_dbmail
@recipients=@recipients,
@subject =@subject,
@body= @body,
@file_attachments=@file_attachments
PRINT '@@ERROR: ' + CONVERT(VARCHAR, @@ERROR)
PRINT 'Retcode ONE: ' + CONVERT(VARCHAR, @retcode)
IF @retcode <> 0
EXEC @retcode = msdb.dbo.sp_send_dbmail
@recipients=@recipients,
@subject =@subject,
@body= @body
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() "sp_send_dbmail: Error Description",ERROR_SEVERITY()"Error Severity"
END CATCH
RETURN @retcode
END
GO
CREATE PROCEDURE dbo.sp_test_send_email
AS
BEGIN
DECLARE @retcode INT
BEGIN TRY
EXEC @retcode = dbo.sp_send_email @recipients='me@somewhere.com', @subject='Test Mail', @body='This is a test', @file_attachments='C:\temp\stage\test.txt'
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() "sp_test_send_email: Error Description",ERROR_SEVERITY()"Error Severity"
END CATCH
RETURN @retcode
END
GO
BEGIN TRY
DECLARE @retcode INT
EXEC @retcode = dbo.sp_test_send_email
PRINT 'Retcode: ' + CONVERT(VARCHAR, @retcode)
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() "test: Error Description",ERROR_SEVERITY()"Error Severity"
END CATCH
这是返回的内容:
Msg 22051,Level 16,State 1,Line 0 无法打开附件文件'C:\ temp \ stage \ test.txt'。执行API'CreateFile'失败,错误号为32。 @@错误:0 Retcode ONE:1 邮件(Id:11)排队。 Retcode:0
电子邮件确实已发送,但Msg 22051永远不会被抓住。这就是导致生产失败的原因。
但是,如果有一些我缺少的东西,并且有一种方法可以从sp_send_dbmail中获取错误,我肯定想知道如何。
谢谢,
雷
答案 0 :(得分:2)
在这里查看sp_send_dbmail的文档: http://msdn.microsoft.com/en-us/library/ms190307.aspx
请注意,您应该使用sp_send_dbmail的返回码,而不是使用/ catch:
返回代码值
返回码0表示成功。任何其他值都意味着失败。该 失败的语句的错误代码存储在@@ ERRROR中 变量
结果集
成功时,返回消息“邮件排队。”
答案 1 :(得分:0)
我使用SQLServer 2008R2。我总是将0作为返回值或引发错误。
例如,当我使用不存在的配置文件时,我将获得以下内容:
ERROR_NUMBER()= 14607 ERROR_MESSAGE()='个人资料名称无效'
我认为更有用的是检查返回值本身。
托梅克