我编写了一个存储过程,用于从给定的.bak文件恢复数据库,并在SQL Server代理的Job中安排此过程。现在,有时会发生以下情况:.bak文件不可用,或者被防病毒软件复制或扫描,或者上帝知道在我的恢复过程中还有什么其他问题引发了操作系统错误(文件被其他进程访问)(并非总是但有时) 。 为了绕过它,我将我的Restore语句放在一个循环中的try-catch块中,如下所示,假设这可能解决问题,但它不是那样工作的。以下是我的程序:
DECLARE @Repeat INT
SET @Repeat = 1
WHILE (@Repeat = 1)
BEGIN
BEGIN TRY
IF DB_ID('MyDBName') IS NOT NULL
BEGIN
DROP DATABASE MyDBName
END
SET @File = @Path+@File --@File contains valid values, no problem in them
print @File
RESTORE FILELISTONLY FROM DISK = @File
--print 'Restore Filelist Successful'
RESTORE DATABASE BSG FROM DISK = @File
WITH REPLACE, MOVE 'ABC_Data' TO 'D:\MyDBName\MyDBName.mdf',
MOVE 'ABC_Log' TO 'D:\MyDBName\MyDBName_1.ldf'
SET @Repeat = 0
--print 'Restore Database Successful'
--print 'Move Successful'
END TRY
BEGIN CATCH
print 'Error Occured'
SET @Repeat = 1
END CATCH
END
请注意,我的程序大部分时间都可以正常工作,例如7/10,但有时当我看到作业历史记录时,我会在失败报告中看到以下错误:
Executed as user: NT AUTHORITY\SYSTEM. In Transaction [SQLSTATE 01000] (Message 0)
'*MyBackupDBFilePath*' [SQLSTATE 01000] (Message 0) Cannot open backup device
'*MyBackupDBFilePath*'. Operating system error 32(The process cannot access the file
because it is being used by another process.). [SQLSTATE 42000] (Error 3201).
The step failed.
我可以看到在访问我的.bak文件时出现了一些问题,但我没有得到的是为什么我的程序没有尝试再次恢复数据库(基本上为什么我的捕获没有捕获失败@重复值为1
答案 0 :(得分:1)
我遇到了TRY CATCH
块在发生错误时没有跳闸的问题,而且它与阻止整个块执行的错误有关。例如,如果您有一个try catch块,用于在发生故障时回滚事务,并且遇到不存在的列。这不是解析错误,但它是一个阻止执行的错误,因此它完全失败。如果我包含
SET XACT_ABORT ON
。
当SET XACT_ABORT为ON时,如果Transact-SQL语句引发运行时错误,则终止并回滚整个事务。
希望这会对你有所帮助。如果没有,那么使用它仍然是一个好主意,我们在使用TRY CATCH
块的作业中使用它,以防万一列被删除或类似的事情。