我现在在程序里链接master,执行其中的一个存储过程可以做到还原MYDATABASE我想知道是否可以直接执行MYDATABASE中存储过程来还原?

解决方案 »

  1.   

    USE master
    GOIF EXISTS (SELECT * FROM sysobjects 
    WHERE id = object_id(N'[dbo].[spForceRestoreDB]') 
    AND OBJECTPROPERTY(id, N'IsProcedure') = 1)
    DROP PROCEDURE [dbo].[spForceRestoreDB]
    GOSET QUOTED_IDENTIFIER  OFF    SET ANSI_NULLS  ON 
    GO/*
       强制还原已存在的数据库
       调用;
       use master
       go
       exec master..spForceRestoreDB 'test'
                                     ,'c:\test.bak'
                                     ,'c:\db\test_data.mdf'
                                     ,'c:\db\test_log.mdf'
    */
    CREATE PROCEDURE spForceRestoreDB
        @DatabaseName varchar(50),       --要恢复的数据库名
        @BackupFile varchar(255),        --备份文件路径
        @NewDataFilePath  varchar(255),  --新物理文件位置
        @NewLogFilePath  varchar(255)    --新日志文件位置
    WITH ENCRYPTION
    AS
    BEGIN
    SET NOCOUNT ON
    DECLARE @exists int IF NOT EXISTS( select name from master.dbo.sysdatabases WHERE name = @DatabaseName)
    BEGIN
    PRINT ' Database ' + @DatabaseName + ' not found '
    PRINT ' Enter valid Datbase name'
    RETURN
    END EXEC master.dbo.xp_fileexist @BackupFile , @exists OUTPUT
    if (@exists = 0)
    BEGIN
    PRINT ' File ' + @BackupFile + ' Does bot Exist'
    PRINT ' Database cannot be restored'
    PRINT ' Enter the valid Backup File'
    RETURN
    END     -- Cursor for all the spids running against this database
    DECLARE SysProc CURSOR LOCAL FORWARD_ONLY DYNAMIC READ_ONLY FOR
    SELECT spid
    FROM master.dbo.sysprocesses
    WHERE dbid = ( SELECT dbid FROM master.dbo.sysdatabases
       WHERE name = @DatabaseName)
      
    DECLARE @SysProcId smallint

    -- Opens the Cursor
    OPEN SysProc

    -- Fetch the Process ID into the cursor
      FETCH NEXT FROM SysProc INTO @SysProcId
     
    DECLARE @KillStatement char(30)

    WHILE @@FETCH_STATUS = 0
    BEGIN
    SET @KillStatement = 'KILL ' + CAST(@SysProcId AS char(30))

    -- Kills the processes running against the database
    EXEC (@KillStatement)

    FETCH NEXT FROM SysProc INTO @SysProcId
    END

    WAITFOR DELAY '000:00:01'        create table # 
           (LogicalName varchar(255), 
            PhysicalName varchar(255), 
            Type varchar(20), 
            FileGroupName varchar(255), 
            Size varchar(20), 
            MaxSize varchar(20) )
            declare @cmd varchar(200)
                    ,@DataLogicName varchar(20)
                    ,@logLogicName varchar(20)
            select @cmd = 'RESTORE FILELISTONLY FROM disk = '''+ @BackupFile + '''' 
            insert # exec(@cmd)        select @DataLogicName=LogicalName from # where Type='D'
            select @logLogicName=LogicalName from # where Type='L'
            drop table # DECLARE @strSql varchar(2000) SET @strSql = 'RESTORE DATABASE '
    SET @strSql = @strSql + QUOTENAME(@DatabaseName)  
    SET @strSql = @strSql + 'FROM  DISK = N'+ '''' + @BackupFile + '''' 
    SET @strSql = @strSql + ' WITH  FILE = 1,  NOUNLOAD ,  STATS = 10,  RECOVERY ,  REPLACE'
            SET @strSql = @strSql + ',Move '''+@DataLogicName+''' to '''+@NewDataFilePath+''''
            SET @strSql = @strSql + ',Move '''+@logLogicName+''' to '''+@NewLogFilePath+'''' --PRINT @strSql
    -- Restore the Database
    EXEC (@strSql)SET NOCOUNT OFF
    END
    GO
      

  2.   

    spForceRestoreDB 还是建立在master下,我想建立在MYDATABASE下
      

  3.   

    想调用MYDATABASE下spForceRestoreDB 来还原spForceRestoreDB
      

  4.   

    上面说错了,应该是:想调用MYDATABASE下spForceRestoreDB 来还原MYDATABASE
      

  5.   

    当然不行啊,
    还原MYDATABASE的命令'RESTORE DATABASE 先必须得到数据库的排他权,
    如果把spForceRestoreDB放在MYDATABASE下,那spForceRestoreDB还在占用MYDATABASE资源
    令'RESTORE DATABASE 就得不到数据库的排他权,所以出错.
    估计用RESTORE DATABASE 强制还原时会先KILL掉正在使用MYDATABASE的所有进程,
    由于在正在使用MYDATABASE的是调用RESTORE DATABASE的父进程,
    自己不能KILL自己,故报错"不能用 KILL 来取消您自己的进程。"