每天晚上,我备份生产服务器并将备份推送到开发服务器。我的开发服务器然后运行一个作业,该作业首先检查备份文件是否退出,如果存在则检查数据库是否存在于dev中,如果存在则删除数据库,然后从文件中还原。除非文件由于传输缓慢等原因尚未完成,否则一切都可以正常工作。如果在作业运行时未完全下载文件,则第一步将看到该文件存在并删除数据库。下一步尝试还原,当然会失败。第二天,当作业运行时,我希望当它检查数据库是否存在时,会看到它不并且不应该尝试删除它并只是还原它。但是,正在发生的事情是该作业无法删除数据库,而此时只是失败。这需要手动干预才能还原数据库,这是我的问题。我不太担心服务器上不存在数据库这一天(理论上)的事实,因为我可以调整时间表以更快地恢复。我担心的是,为什么IF语句无法检查数据库是否存在并尝试删除数据库?这是我正在使用的T-SQL代码:
DECLARE @output INT
DECLARE @SqlPath varchar(500) = 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Backup\PROD-01_prod_backup.bak'
EXECUTE master.dbo.xp_fileexist @SqlPath, @output OUT
IF @output = 1
BEGIN
IF (EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE ('[' + name + ']' = '[PROD-01]')))
BEGIN
ALTER DATABASE [PROD-01] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DROP DATABASE [PROD-01]
END
RESTORE DATABASE [PROD-01] FROM DISK = @SqlPath
END
答案 0 :(得分:0)
由于无法复制,因此我不确定这是怎么发生的,但是对于这种情况,TRY / CATCH
块是理想的解决方案:
SET XACT_ABORT ON
GO
DECLARE @output INT
DECLARE @SqlPath varchar(500) = 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Backup\PROD-01_prod_backup.bak'
EXECUTE master.dbo.xp_fileexist @SqlPath, @output OUT
IF @output = 1
BEGIN
IF (EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE (name = 'PROD-01')))
BEGIN TRY
ALTER DATABASE [PROD-01] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DROP DATABASE [PROD-01]
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE();
END CATCH
RESTORE DATABASE [PROD-01] FROM DISK = @SqlPath
END