1 USE [master]
2 GO
3 /****** Object: StoredProcedure [dbo].[pr_restore_db] Script Date: 08/27/2012 14:19:31 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8 /*恢复数据库*/
9 ALTER proc [dbo].[pr_restore_db]
10 /*
11 ------------------------------------------------
12 Create Time: 2004-03-20
13 Update Time: 2004-03-29 11:05
14 Author: aierong
15 Remark: 恢复数据库
16
17 ------------------------------------------------
18 */
19 /*过程运行的状态标志,是输入参数*/
20 @flag varchar(20) out,
21 /*要恢复的数据名字*/
22 @restore_db_name nvarchar(128),
23 /*备份文件存放的路径+备份文件名字*/
24 @filename nvarchar(260)
25 as
26 /*返回系统存储过程xp_cmdshell运行结果*/
27 declare @proc_result tinyint
28 /*循环次数*/
29 declare @loop_time smallint
30 /*@tem表的ids列最大数*/
31 declare @max_ids smallint
32 /*原数据库存放路径*/
33 declare @file_bak_path nvarchar(260)
34 /*文件存放标志*/
35 declare @flag_file bit
36 /*数据库master文件路径*/
37 declare @master_path nvarchar(260)
38 declare @sql nvarchar(4000),@par nvarchar(1000)
39 declare @sql_sub nvarchar(4000)
40 declare @sql_cmd nvarchar(100)
41 declare @sql_kill nvarchar(100)
42 /*
43 判断参数@filename文件格式合法性,以防止用户输入类似d: 或者 c:a 等非法文件名
44 参数@filename里面必须有''并且不以''结尾
45 */
46 --if right(@filename,1)<>'' and charindex('',@filename)<>0
47 if right(@filename,1)<>'\' and charindex('\',@filename)<>0
48 begin
49 select @sql_cmd='dir '+@filename
50 EXEC @proc_result = master..xp_cmdshell @sql_cmd,no_output
51 /*系统存储过程xp_cmdshell返回代码值:0(成功)或1(失败)*/
52 IF (@proc_result<>0)
53 begin
54 /*备份文件不存在*/
55 select @flag='not exist'
56 /*退出过程*/
57 return
58 end
59 /*创建临时表,保存由备份集内包含的数据库和日志文件列表组成的结果集*/
60 create table #tem(
61 /*文件的逻辑名称*/
62 LogicalName nvarchar(128),
63 /*文件的物理名称或操作系统名称*/
64 PhysicalName nvarchar(260) ,
65 /*数据文件 (D) 或日志文件 (L)*/
66 Type char(1),
67 /*包含文件的文件组名称*/
68 FileGroupName nvarchar(128),
69 /*当前大小(以字节为单位)*/
70 [Size] numeric(20,0),
71 /*允许的最大大小(以字节为单位)*/
72 [MaxSize] numeric(20,0)
73 )
74 /*
75 创建表变量,表结构与临时表基本一样
76 就是多了两列,
77 列ids(自增编号列),
78 列file_path,存放文件的路径
79 */
80 declare @tem table(
81 /*自增编号列*/
82 ids smallint identity,
83 LogicalName nvarchar(128),
84 PhysicalName nvarchar(260),
85 File_path nvarchar(260),
86 Type char(1),
87 FileGroupName nvarchar(128)
88 )
89 insert into #tem
90 execute('restore filelistonly from disk='''+@filename+'''')
91 /*将临时表导入表变量中,并且计算出相应得路径*/
92 insert into @tem(LogicalName,PhysicalName,File_path,Type,FileGroupName)
93 select LogicalName,PhysicalName,dbo.fn_GetFilePath(PhysicalName),Type,FileGroupName
94 from #tem
95 if @@rowcount>0
96 begin
97 drop table #tem
98 end
99 select @loop_time=1
100 /*@tem表的ids列最大数*/
101 select @max_ids=max(ids)
102 from @tem
103 while @loop_time<=@max_ids
104 begin
105 select @file_bak_path=file_path
106 from @tem where ids=@loop_time
107 select @sql_cmd='dir '+@file_bak_path
108 EXEC @proc_result = master..xp_cmdshell @sql_cmd,no_output
109 /*系统存储过程xp_cmdshell返回代码值:0(成功)或1(失败)*/
110 IF (@proc_result<>0)
111 select @loop_time=@loop_time+1
112 else
113 /*没有找到备份前数据文件原有存放路径,退出循环*/
114 BREAK
115 end
116 select @master_path=''
117 if @loop_time>@max_ids
118 /*备份前数据文件原有存放路径存在*/
119 select @flag_file=1
120 else
121 begin
122 /*备份前数据文件原有存放路径不存在*/
123 select @flag_file=0
124 select @master_path=dbo.fn_GetFilePath(filename)
125 from master..sysdatabases
126 where name='master'
127 end
128 select @sql_sub=''
129 /*type='d'是数据文件,type='l'是日志文件 */
130 /*@flag_file=1时新的数据库文件还是存放在原来路径,否则存放路径和master数据库路径一样*/
131 select @sql_sub=@sql_sub+'move '''+LogicalName+''' to '''
132 +case type
133 when 'd' then case @flag_file
134 when 1 then File_path
135 else @master_path
136 end
137 when 'l' then case @flag_file
138 when 1 then File_path
139 else @master_path
140 end
141 end
142 +case type
143 when 'd' then @restore_db_name
144 +'_DATA'
145 /*给文件编号*/
146 +convert(sysname,ids)
147 +'.'
148 /*给文件加入后缀名,mdf or ndf*/
149 +right(PhysicalName,3)
150 +''','
151 when 'l' then @restore_db_name
152 +'_LOG'
153 /*给文件编号*/
154 +convert(sysname,ids)
155 +'.'
156 /*给文件加入后缀名,mdf or ndf*/
157 +right(PhysicalName,3)
158 +''','
159 end
160 from @tem
161 select @sql='RESTORE DATABASE @db_name '
162 +'FROM DISK=@filename with '
163 select @sql=@sql+@sql_sub+'replace'
164 select @par='@db_name nvarchar(128),@filename nvarchar(260)'
165 /*关闭相关进程,把相应进程状况导入临时表中*/
166 select identity(int,1,1) ids, spid
167 into #temp
168 from master..sysprocesses
169 where dbid=db_id(@restore_db_name)
170 /*找到相应进程*/
171 if @@rowcount>0
172 begin
173 select @max_ids=max(ids)
174 from #temp
175 select @loop_time=1
176 while @loop_time<=@max_ids
177 begin
178 select @sql_kill='kill '+convert(nvarchar(20),spid)
179 from #temp
180 where ids=@loop_time
181 execute sp_executesql @sql_kill
182 select @loop_time=@loop_time+1
183 end
184 end
185 drop table #temp
186 execute sp_executesql @sql,
187 @par,
188 @db_name=@restore_db_name,
189 @filename=@filename
190 /*操作成功*/
191 select @flag='ok'
192 end
193 else
194 begin
195 /*参数@filename输入格式错误*/
196 SELECT @flag='file type error'
197 end