方法是先提取原数据库名,再提取数据库相关的数据文件(数据文件和日志文件),然后还原数据库。
代码如下:
Use
master
Go
If
Object_id
(
'
sp_RestoreDataBase
'
)
Is
Not
Null
Drop
Proc
sp_RestoreDataBase
Go
Create
Proc
sp_RestoreDataBase
(
@DataBaseBakPath
nvarchar
(
260
),
@DataBaseNewPath
nvarchar
(
260
)
)
As
Set
Nocount
On
Declare
@Sql
nvarchar
(
max
),
@DataBase
nvarchar
(
128
)
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
)
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
@DataBakHeader
Exec
sp_executesql N
'
Restore HeaderOnly From Disk=@DataBaseBakPath
'
,N
'
@DataBaseBakPath nvarchar(260)
'
,
@DataBaseBakPath
Insert
Into
@DataBakFileList
Exec
sp_executesql N
'
Restore FileListOnly From Disk=@DataBaseBakPath
'
,N
'
@DataBaseBakPath nvarchar(260)
'
,
@DataBaseBakPath
Select
@DataBase
=
DatabaseName
From
@DataBakHeader
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
+
'
\
'
+
LogicalName
+Right
(PhysicalName,
Charindex
(
'
.
'
,
Reverse
(PhysicalName)))
+
'''
,
'
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
e.g:
Exec
sp_RestoreDataBase
'
F:\SQL2005\test1\deadlocktest.bak
'
,
'
F:\SQL2005\test2\
'
/*
还原数据库: deadlocktest
已处理百分之 10。
已处理百分之 20。
已处理百分之 30。
已处理百分之 40。
已处理百分之 50。
已处理百分之 60。
已处理百分之 70。
已处理百分之 80。
已处理百分之 90。
已处理百分之 100。
已为数据库 'deadlocktest',文件 'deadlocktest' (位于文件 1 上)处理了 1184 页。
已为数据库 'deadlocktest',文件 'deadlocktest_log' (位于文件 1 上)处理了 2 页。
RESTORE DATABASE 成功处理了 1186 页,花费 0.495 秒(19.613 MB/秒)。
*/