2012-08-06 48 views
3

我在SQL Server 2008 R2的数据库,我创建了恢复数据库此存储过程:还原存储过程

CREATE PROCEDURE [dbo].[usp_DBRestore] 
@DBName nvarchar(60) 
,@BackName nvarchar(120) 
,@OutMessage nvarchar(4000) output 
--, 
[email protected] varchar(60), 
[email protected] varchar(120), 
[email protected] varchar(60), 
[email protected] varchar(120) 
AS 

BEGIN TRY 
    USE [master] 

    ALTER DATABASE @DBName SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
    RESTORE DATABASE @DBName FROM 
     DISK = @BackName WITH 
     FILE = 1, NOUNLOAD, 
     REPLACE, 
     PASSWORD = 'TEST' 
    SET @OutMessage = 'OK'; 
    ALTER DATABASE @DBName SET MULTI_USER WITH ROLLBACK IMMEDIATE 
END TRY 
BEGIN CATCH 

    ALTER DATABASE @DBName SET MULTI_USER WITH ROLLBACK IMMEDIATE 

    INSERT [dbo].[ErrorLog] 
    (
    [UserName], 
    [ErrorNumber], 
    [ErrorSeverity], 
    [ErrorState], 
    [ErrorProcedure], 
    [ErrorLine], 
    [ErrorMessage] 
    ) 
    VALUES(
      CONVERT(sysname, CURRENT_USER), 
      ERROR_NUMBER(), 
      ERROR_SEVERITY(), 
      ERROR_STATE(), 
      ERROR_PROCEDURE(), 
      ERROR_LINE(), 
      ERROR_MESSAGE() 

     ) 
END CATCH 

当我执行的代码,我看到这个错误:

一个USE数据库声明不允许在程序,函数或触发器中使用。

我该如何解决这个错误?

+2

**不要在您的存储过程中拥有'USE ...'......这实际上只是**解决方案。为什么在存储过程中需要这个?你不能把它作为一个独立的查询吗? (这就是我所做的) – 2012-08-06 09:38:56

+3

即使你的数据库中没有'USE master',这个'ALTER DATABASE @ DBName'也不起作用,因为你不能指定数据库名作为参数。 .. – 2012-08-06 09:40:13

回答

0

您不需要USE语句。最好的办法是删除使用语句,并在master数据库本身上创建/更改此sp。

如果要进行备份,请从主数据库执行此SP。我看不到任何其他出路。

1

你不能以这种方式做到这一点 - 你基本上有两种选择:

  1. 棒存储过程,但在这种情况下,你必须使用动态SQL。您的存储过程将创建一串SQL语句,允许其使用USE master,并允许它动态设置数据库名称等,然后使用sp_executesql @sqlRestoreStatement执行该SQL语句。如果你想看看这个,你MUST是一切手段阅读(和理解)厄兰Sommarskog的开创性文章The Curse and Blessings of Dynamic SQL

  2. 可以使用常规的SQL脚本,可能与SQLCMD占位符(如果你有SQLCMD mode在启用了SQL Server Management Studio),并从常规脚本执行还原(例如,您可以将其放入自己的模板文件夹中)。在这种情况下,你会碰到这样的:

    :setvar dbname YourDatabaseNameHere 
    
    DECLARE @FileName NVARCHAR(255) 
    SET @FileName = N'D:\YourBackupDirectory\SomeDatabase.bak' 
    
    RESTORE DATABASE [$(dbname)] 
    FROM DISK = @FileName 
    WITH FILE = 1, 
    MOVE N'YourDatabase_Data' TO N'D:\MSSQL\Data\$(dbname).mdf', 
    MOVE N'YourDatbase_Log' TO N'D:\MSSQL\Data\$(dbname)_Log.ldf', 
    NOUNLOAD, REPLACE, 
    STATS = 2 
    GO 
    

    有了这个设置,您可以方便地使用SQL脚本作为模板,恢复使用任何一种数据库。

0

你为什么不保存在master数据库中该存储过程?这对你来说会是一个问题吗?