根据备份文件直接还原数据库(V2.0)

时间:2022-10-09 20:41:39

代码如下:

Use  master
Go
If   Object_id ( ' sp_RestoreDataBase ' Is   Not   Null
    
Drop   Proc  sp_RestoreDataBase
Go
/* 根据备份文件直接还原数据库V2.0 Andy 2008-10-5 */
Create   Proc  sp_RestoreDataBase
(
    
@DataBaseBakPath   nvarchar ( 260 ),
    
@DataBaseNewPath   nvarchar ( 260 ),
    
@DataBaseNewName   nvarchar ( 128 ) = null
)
As
Set  Nocount  On
Declare
    
@Sql   nvarchar ( 4000 ),
    
@DataBase   nvarchar ( 128 ),
    
@SqlAlterDataBase   nvarchar ( 4000 )

If   Isnull ( @DataBaseNewName , '' ) > ''
    
Set   @DataBase = @DataBaseNewName
Else
Begin
    
Declare   @DataBakHeader   table (BackupName  nvarchar ( 128 ),BackupDescription  nvarchar ( 255 ),BackupType  smallint ,ExpirationDate  datetime ,Compressed  tinyint ,Position  smallint ,DeviceType  tinyint ,UserName  nvarchar ( 128 ),ServerName  nvarchar ( 128 ),DatabaseName  nvarchar ( 128 ),DatabaseVersion  int ,DatabaseCreationDate  datetime ,BackupSize numeric( 20 , 0 ),FirstLSN numeric( 25 , 0 ),LastLSN numeric( 25 , 0 ),CheckpointLSN numeric( 25 , 0 ),DatabaseBackupLSN numeric( 25 , 0 ),BackupStartDate  datetime ,BackupFinishDate  datetime ,SortOrder  smallint ,CodePage  smallint ,UnicodeLocaleId  int ,UnicodeComparisonStyle  int ,CompatibilityLevel  tinyint ,SoftwareVendorId  int ,SoftwareVersionMajor  int ,SoftwareVersionMinor  int ,SoftwareVersionBuild  int ,MachineName  nvarchar ( 128 ),Flags   int ,BindingID  uniqueidentifier ,RecoveryForkID  uniqueidentifier ,Collation  nvarchar ( 128 ),FamilyGUID  uniqueidentifier ,HasBulkLoggedData  bit ,IsSnapshot  bit ,IsReadOnly  bit ,IsSingleUser  bit ,HasBackupChecksums  bit ,IsDamaged  bit ,BeginsLogChain  bit ,HasIncompleteMetaData  bit ,IsForceOffline  bit ,IsCopyOnly  bit ,FirstRecoveryForkID  uniqueidentifier ,ForkPointLSN numeric( 25 , 0 NULL ,RecoveryModel  nvarchar ( 60 ),DifferentialBaseLSN numeric( 25 , 0 NULL ,DifferentialBaseGUID  uniqueidentifier ,BackupTypeDescription  nvarchar ( 60 ),BackupSetGUID  uniqueidentifier   NULL )
    
Insert   Into   @DataBakHeader
    
Exec  sp_executesql N ' Restore HeaderOnly From Disk=@DataBaseBakPath ' ,N ' @DataBaseBakPath nvarchar(260) ' , @DataBaseBakPath
    
Select   @DataBase = DatabaseName  From   @DataBakHeader
End

Declare   @DataBakFileList   table (LogicalName  nvarchar ( 128 ),PhysicalName  nvarchar ( 260 ),Type  char ( 1 ),FileGroupName  nvarchar ( 128 ),Size numeric( 20 , 0 ),MaxSize numeric( 20 , 0 ),FileId  bigint ,CreateLSN numeric( 25 , 0 ),DropLSN numeric( 25 , 0 NULL ,UniqueID  uniqueidentifier ,ReadOnlyLSN numeric( 25 , 0 NULL ,ReadWriteLSN numeric( 25 , 0 NULL ,BackupSizeInBytes  bigint ,SourceBlockSize  int ,FileGroupID  int ,LogGroupGUID  uniqueidentifier   NULL ,DifferentialBaseLSN numeric( 25 , 0 NULL ,DifferentialBaseGUID  uniqueidentifier ,IsReadOnly  bit ,IsPresent  bit )
Insert   Into   @DataBakFileList
Exec  sp_executesql N ' Restore FileListOnly From Disk=@DataBaseBakPath ' ,N ' @DataBaseBakPath nvarchar(260) ' , @DataBaseBakPath

Select   @Sql = Isnull ( @Sql + Char ( 13 ) + Char ( 10 ), '' ) + ' Kill  ' + Rtrim (spid)  From  master.sys.sysprocesses  Where  dbid = db_id ( @DataBase )

Set   @Sql = Isnull ( @Sql + Char ( 13 ) + Char ( 10 ), '' ) + ' Restore DataBase @DataBase From Disk=@DataBaseBakPath With  '

Select      @Sql = @Sql + ' Move ''' + LogicalName + '''  To  ''' + @DataBaseNewPath + ' \ ' +
            
Case   
                
When  Type = N ' D '   And   Isnull ( @DataBaseNewName , '' ) > ''   Then   @DataBase + N ' _Data '  
                
When  Type = N ' L '   And   Isnull ( @DataBaseNewName , '' ) > ''   Then   @DataBase + N ' _Log '  
                
Else  LogicalName 
            
End   +Right (PhysicalName, Charindex ( ' . ' , Reverse (PhysicalName))) + ''' , ' ,

        
@SqlAlterDataBase = Isnull ( @SqlAlterDataBase + Char ( 13 ) + Char ( 10 ),
            
Case   Isnull ( @DataBaseNewName , ''
                
When   ''   Then   null  
                
Else   ''  
            
End ) + ' Alter DataBase  ' + Quotename ( @DataBase ) + '  Modify File(Name= ' + LogicalName + ' ,NewName= ' + @DataBase + Case  Type  When  N ' D '   Then  N ' _Data '   Else  N ' _Log '   End + ' ) '
    
From   @DataBakFileList

Set   @Sql = @Sql + ' Replace,Stats=10 '

Set  Nocount  Off
Print   ' 还原数据库:  ' + @DataBase

Exec  sp_executesql  @Sql ,N ' @DataBase nvarchar(128),@DataBaseBakPath nvarchar(260) ' , @DataBase , @DataBaseBakPath

If   @SqlAlterDataBase > ''
    
Exec ( @SqlAlterDataBase )

 

调用测试:

Exec  sp_RestoreDataBase  ' F:\SQL2005\test1\deadlocktest.bak ' , ' F:\SQL2005\test2 ' , ' Test3 '

测试结果:

还原数据库: Test3
已处理百分之 10。
已处理百分之 20。
已处理百分之 30。
已处理百分之 40。
已处理百分之 50。
已处理百分之 60。
已处理百分之 70。
已处理百分之 80。
已处理百分之 90。
已处理百分之 100。
已为数据库 'Test3',文件 'deadlocktest' (位于文件 1 上)处理了 1184 页。
已为数据库 'Test3',文件 'deadlocktest_log' (位于文件 1 上)处理了 2 页。
RESTORE DATABASE 成功处理了 1186 页,花费 0.552 秒(17.587 MB/秒)。
文件 名称 'Test3_Data' 已设置。
文件 名称 'Test3_Log' 已设置。

 

上一篇《根据备份文件直接还原数据库》可以参考:

http://www.cnblogs.com/wghao/archive/2008/07/27/1254213.html

(完)