问题
We use sp_send_dbmail to notify us of certain problems and sometimes we attach files to the emails. Occasionally we will get an Error 32 (file in use) error. I've put some code together to send the email without the attachment in this situation but no matter what I do I'm unable to CATCH the error and ignore it.
I'd like to be able to handle or ignore any errors from sp_send_dbmail because this causes a job failure in production.
I tried implementing the technique described in this article http://www.sqlusa.com/articles2008/trycatch/ like so:
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
This is what gets returned:
Msg 22051, Level 16, State 1, Line 0 Failed to open attachment file 'C:\temp\stage\test.txt'. Executing API 'CreateFile' failed with error number 32. @@ERROR: 0 Retcode ONE: 1 Mail (Id: 11) queued. Retcode: 0
The email does get sent but the Msg 22051 never gets caught. This is what causes the failure in production.
This may be the way it is: http://connect.microsoft.com/SQLServer/feedback/details/687544/2008-sp1-engine-sp-send-dbmail-does-not-fall-into-a-catch-block-properly
However, if there is something I'm missing and there is a way to eat the errors from sp_send_dbmail I'd sure like to know how.
Thanks,
Ray
回答1:
Take a look at the documentation for sp_send_dbmail here: http://msdn.microsoft.com/en-us/library/ms190307.aspx
Notice you should use the return code from sp_send_dbmail and not try/catch:
Return Code Values
A return code of 0 means success. Any other value means failure. The error code for the statement that failed is stored in the @@ERRROR variable.
Result Sets
On success, returns the message "Mail queued."
回答2:
I use SQLServer 2008R2. I always have either 0 as the return value or an error raised.
For example, when I use an nonexisting profile I'm obtaining the following:
ERROR_NUMBER() = 14607 ERROR_MESSAGE() = 'profile name is not valid'
Which I consider much more usefull then checking return value itself.
Tomek
来源:https://stackoverflow.com/questions/16109138/cant-catch-errors-from-sp-send-dbmail