我有以下示例T-SQL代码,BEGIN TRY
BEGIN TRY
BEGIN TRANSACTION
RESTORE FILELISTONLY
FROM DISK = 'D:\Backup\MyDatabase.bak'
GO
ALTER DATABASE MyDatabase
SET SINGLE_USER WITH
ROLLBACK IMMEDIATE
ALTER DATABASE MyDatabase
SET RECOVERY Simple
----Restore Database
RESTORE DATABASE MyDatabase
FROM DISK = 'D:\Backup\MyDatabase.bak'
WITH MOVE 'MyDatabase' TO 'C:\DataFolder\MyDatabase.mdf',
MOVE 'MyDatabase_log' TO 'C:\DataFolder\MyDatabase_log.ldf'
ALTER DATABASE MyDatabase SET MULTI_USER
GO
USE [MyDatabase]
IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N'user1')
CREATE USER [user1] FOR LOGIN [user1] WITH DEFAULT_SCHEMA=[user1]
GO
EXEC sp_addrolemember 'db_owner',N'user1'
GO
COMMIT
--Send email on successfull execution of script
USE [msdb];
EXEC sp_send_dbmail @profile_name='My Mail Profile',
@recipients='myemail@mydomain.org',
@subject='Test subject',
@query = '',
@body='Tested successfully.'
END TRY
BEGIN CATCH
--If there is any error in the script, roll back the transaction and also send an error report email notification
ROLLBACK
USE [msdb];
EXEC sp_send_dbmail @profile_name='My Mail Profile',
@recipients='myemail@mydomain.org',
@subject='Test error',
@body= ERROR_MESSAGE()
END CATCH
该代码抛出以下错误,
Msg 102,Level 15,State 1,Line 4 'D:\ Backup \ MyDatabase.bak'附近的语法不正确。
Msg 102,Level 15,State 1,Line 10 'BEGIN'附近的语法不正确。
Msg 102,Level 15,State 1,Line 17 ')'附近的语法不正确。
但是如果我将代码移出BEGIN TRY和BEGIN TRANSACTION块,它会成功执行而不会出现任何错误。
我想要实现的只是执行该T-SQL脚本,如果失败,我通知我向某个电子邮件帐户发送通知,其中包含导致电子邮件正文中的代码失败的错误消息。
关于如何更好地实现这一目标的任何建议都是非常受欢迎的。
答案 0 :(得分:3)
TRY / CATCH块只能在单个请求(批处理)的范围内使用。您试图跨越几个批次的TRY块。 GO
是默认的批处理分隔符,fyi。
您还希望支持某些不支持交易的操作的交易和回滚,例如RESTORE
:
在显式或隐式事务中不允许RESTORE。
您可以更好地在更高级别,应用程序甚至脚本中处理此类问题。请注意,sqlcmd
支持-b
选项在第一次出错时中断,您可以使用退出代码(%ERRORLEVEL%
)。
答案 1 :(得分:1)
第一个问题是第5行中的“go”语句... sql server试图执行到目前为止的行,但这不起作用,因为你有一个没有相应的结束尝试的开始尝试...