• 备份与恢复数据库的存储过程


     
    备份与恢复数据库的存储过程
    1.   
    2. 这种方式感觉实现起来也不错,我是使用这种方式来完成数据库备份还原的功能的。    
    3. 需要指出下面这些存储过程是在网上搜索到的。谢谢代码的提供者。在此转载    
    4.   
    5. 利用T-SQL语句,实现数据库的备份与还原的功能    
    6.   
    7. 体现了SQL Server中的四个知识点:    
    8.   
    9. 1. 获取SQL Server服务器上的默认目录    
    10.   
    11. 2. 备份SQL语句的使用    
    12.   
    13. 3. 恢复SQL语句的使用,同时考虑了强制恢复时关闭其他用户进程的处理    
    14.   
    15. 4. 作业创建SQL语句的使用    
    16.   
    17.   
    18.   
    19. /*1.--得到数据库的文件目录   
    20.  
    21. @dbname 指定要取得目录的数据库名   
    22. 如果指定的数据不存在,返回安装SQL时设置的默认数据目录   
    23. 如果指定NULL,则返回默认的SQL备份目录名   
    24. */    
    25.   
    26. /*--调用示例   
    27. select 数据库文件目录=dbo.f_getdbpath('tempdb')   
    28. ,[默认SQL SERVER数据目录]=dbo.f_getdbpath('')   
    29. ,[默认SQL SERVER备份目录]=dbo.f_getdbpath(null)   
    30. --*/    
    31. if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_getdbpath]') and xtype in (N'FN', N'IF', N'TF'))    
    32. drop function [dbo].[f_getdbpath]    
    33. GO    
    34.   
    35. create function f_getdbpath(@dbname sysname)    
    36. returns nvarchar(260)    
    37. as    
    38. begin    
    39. declare @re nvarchar(260)    
    40. if @dbname is null or db_id(@dbname) is null    
    41. select @re=rtrim(reverse(filename)) from master..sysdatabases where name='master'    
    42. else    
    43. select @re=rtrim(reverse(filename)) from master..sysdatabases where name=@dbname    
    44.   
    45. if @dbname is null    
    46. set @re=reverse(substring(@re,charindex('\',@re)+5,260))+'BACKUP'    
    47. else    
    48. set @re=reverse(substring(@re,charindex('\',@re),260))    
    49. return(@re)    
    50. end    
    51. go    
    52.   
    53.   
    54. /*2.--备份数据库   
    55.  
    56. */    
    57.   
    58. /*--调用示例   
    59.  
    60. --备份当前数据库   
    61. exec p_backupdb @bkpath='c:\',@bkfname='db_\DATE\_db.bak'   
    62.  
    63. --差异备份当前数据库   
    64. exec p_backupdb @bkpath='c:\',@bkfname='db_\DATE\_df.bak',@bktype='DF'   
    65.  
    66. --备份当前数据库日志   
    67. exec p_backupdb @bkpath='c:\',@bkfname='db_\DATE\_log.bak',@bktype='LOG'   
    68.  
    69. --*/    
    70.   
    71. if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_backupdb]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)    
    72. drop procedure [dbo].[p_backupdb]    
    73. GO    
    74.   
    75. create proc p_backupdb    
    76. @dbname sysname='', --要备份的数据库名称,不指定则备份当前数据库    
    77. @bkpath nvarchar(260)='', --备份文件的存放目录,不指定则使用SQL默认的备份目录    
    78. @bkfname nvarchar(260)='', --备份文件名,文件名中可以用\DBNAME\代表数据库名,\DATE\代表日期,\TIME\代表时间    
    79. @bktype nvarchar(10)='DB', --备份类型:'DB'备份数据库,'DF' 差异备份,'LOG' 日志备份    
    80. @appendfile bit=1 --追加/覆盖备份文件    
    81. as    
    82. declare @sql varchar(8000)    
    83. if isnull(@dbname,'')='' set @dbname=db_name()    
    84. if isnull(@bkpath,'')='' set @bkpath=dbo.f_getdbpath(null)    
    85. if isnull(@bkfname,'')='' set @bkfname='\DBNAME\_\DATE\_\TIME\.BAK'    
    86. set @bkfname=replace(replace(replace(@bkfname,'\DBNAME\',@dbname)    
    87. ,'\DATE\',convert(varchar,getdate(),112))    
    88. ,'\TIME\',replace(convert(varchar,getdate(),108),':',''))    
    89. set @sql='backup '+case @bktype when 'LOG' then 'log ' else 'database ' end +@dbname    
    90. +' to disk='''+@bkpath+@bkfname    
    91. +''' with '+case @bktype when 'DF' then 'DIFFERENTIAL,' else '' end    
    92. +case @appendfile when 1 then 'NOINIT' else 'INIT' end    
    93. print @sql    
    94. exec(@sql)    
    95. go    
    96.   
    97.   
    98.   
    99. /*3.--恢复数据库   
    100.  
    101. */    
    102.   
    103. /*--调用示例   
    104. --完整恢复数据库   
    105. exec p_RestoreDb @bkfile='c:\db_20031015_db.bak',@dbname='db'   
    106.  
    107. --差异备份恢复   
    108. exec p_RestoreDb @bkfile='c:\db_20031015_db.bak',@dbname='db',@retype='DBNOR'   
    109. exec p_backupdb @bkfile='c:\db_20031015_df.bak',@dbname='db',@retype='DF'   
    110.  
    111. --日志备份恢复   
    112. exec p_RestoreDb @bkfile='c:\db_20031015_db.bak',@dbname='db',@retype='DBNOR'   
    113. exec p_backupdb @bkfile='c:\db_20031015_log.bak',@dbname='db',@retype='LOG'   
    114.  
    115. --*/    
    116.   
    117. if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_RestoreDb]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)    
    118. drop procedure [dbo].[p_RestoreDb]    
    119. GO    
    120.   
    121. create proc p_RestoreDb    
    122. @bkfile nvarchar(1000), --定义要恢复的备份文件名    
    123. @dbname sysname='', --定义恢复后的数据库名,默认为备份的文件名    
    124. @dbpath nvarchar(260)='', --恢复后的数据库存放目录,不指定则为SQL的默认数据目录    
    125. @retype nvarchar(10)='DB', --恢复类型:'DB'完事恢复数据库,'DBNOR' 为差异恢复,日志恢复进行完整恢复,'DF' 差异备份的恢复,'LOG' 日志恢复    
    126. @filenumber int=1, --恢复的文件号    
    127. @overexist bit=1, --是否覆盖已经存在的数据库,仅@retype为    
    128. @killuser bit=1 --是否关闭用户使用进程,仅@overexist=1时有效    
    129. as    
    130. declare @sql varchar(8000)    
    131.   
    132. --得到恢复后的数据库名    
    133. if isnull(@dbname,'')=''    
    134. select @sql=reverse(@bkfile)    
    135. ,@sql=case when charindex('.',@sql)=0 then @sql    
    136. else substring(@sql,charindex('.',@sql)+1,1000) end    
    137. ,@sql=case when charindex('\',@sql)=0 then @sql    
    138. else left(@sql,charindex('\',@sql)-1) end    
    139. ,@dbname=reverse(@sql)    
    140.   
    141. --得到恢复后的数据库存放目录    
    142. if isnull(@dbpath,'')='' set @dbpath=dbo.f_getdbpath('')    
    143.   
    144. --生成数据库恢复语句    
    145. set @sql='restore '+case @retype when 'LOG' then 'log ' else 'database ' end+@dbname    
    146. +' from disk='''+@bkfile+''''    
    147. +' with file='+cast(@filenumber as varchar)    
    148. +case when @overexist=1 and @retype in('DB','DBNOR') then ',replace' else '' end    
    149. +case @retype when 'DBNOR' then ',NORECOVERY' else ',RECOVERY' end    
    150. print @sql    
    151. --添加移动逻辑文件的处理    
    152. if @retype='DB' or @retype='DBNOR'    
    153. begin    
    154. --从备份文件中获取逻辑文件名    
    155. declare @lfn nvarchar(128),@tp char(1),@i int    
    156.   
    157. --创建临时表,保存获取的信息    
    158. create table #tb(ln nvarchar(128),pn nvarchar(260),tp char(1),fgn nvarchar(128),sz numeric(20,0),Msz numeric(20,0))    
    159. --从备份文件中获取信息    
    160. insert into #tb exec('restore filelistonly from disk='''+@bkfile+'''')    
    161. declare #f cursor for select ln,tp from #tb    
    162. open #f    
    163. fetch next from #f into @lfn,@tp    
    164. set @i=0    
    165. while @@fetch_status=0    
    166. begin    
    167. select @sql=@sql+',move '''+@lfn+''' to '''+@dbpath+@dbname+cast(@i as varchar)    
    168. +case @tp when 'D' then '.mdf''' else '.ldf''' end    
    169. ,@i=@i+1    
    170. fetch next from #f into @lfn,@tp    
    171. end    
    172. close #f    
    173. deallocate #f    
    174. end    
    175.   
    176. --关闭用户进程处理    
    177. if @overexist=1 and @killuser=1    
    178. begin    
    179. declare @spid varchar(20)    
    180. declare #spid cursor for    
    181. select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)    
    182. open #spid    
    183. fetch next from #spid into @spid    
    184. while @@fetch_status=0    
    185. begin    
    186. exec('kill '+@spid)    
    187. fetch next from #spid into @spid    
    188. end    
    189. close #spid    
    190. deallocate #spid    
    191. end    
    192.   
    193. --恢复数据库    
    194. exec(@sql)    
    195.   
    196. go    
    197.   
    198. /*4.--创建作业   
    199.  
    200. */    
    201.   
    202. /*--调用示例   
    203.  
    204. --每月执行的作业   
    205. exec p_createjob @jobname='mm',@sql='select * from syscolumns',@freqtype='month'   
    206.  
    207. --每周执行的作业   
    208. exec p_createjob @jobname='ww',@sql='select * from syscolumns',@freqtype='week'   
    209.  
    210. --每日执行的作业   
    211. exec p_createjob @jobname='a',@sql='select * from syscolumns'   
    212.  
    213. --每日执行的作业,每天隔4小时重复的作业   
    214. exec p_createjob @jobname='b',@sql='select * from syscolumns',@fsinterval=4   
    215.  
    216. --*/    
    217. if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_createjob]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)    
    218. drop procedure [dbo].[p_createjob]    
    219. GO    
    220.   
    221. create proc p_createjob    
    222. @jobname varchar(100), --作业名称    
    223. @sql varchar(8000), --要执行的命令    
    224. @dbname sysname='', --默认为当前的数据库名    
    225. @freqtype varchar(6)='day', --时间周期,month 月,week 周,day 日    
    226. @fsinterval int=1, --相对于每日的重复次数    
    227. @time int=170000 --开始执行时间,对于重复执行的作业,将从0点到23:59分    
    228. as    
    229. if isnull(@dbname,'')='' set @dbname=db_name()    
    230.   
    231. --创建作业    
    232. exec msdb..sp_add_job @job_name=@jobname    
    233.   
    234. --创建作业步骤    
    235. exec msdb..sp_add_jobstep @job_name=@jobname,    
    236. @step_name = '数据处理',    
    237. @subsystem = 'TSQL',    
    238. @database_name=@dbname,    
    239. @command = @sql,    
    240. @retry_attempts = 5, --重试次数    
    241. @retry_interval = 5 --重试间隔    
    242.   
    243. --创建调度    
    244. declare @ftype int,@fstype int,@ffactor int    
    245. select @ftype=case @freqtype when 'day' then 4    
    246. when 'week' then 8    
    247. when 'month' then 16 end    
    248. ,@fstype=case @fsinterval when 1 then 0 else 8 end    
    249. if @fsinterval<>1 set @time=0    
    250. set @ffactor=case @freqtype when 'day' then 0 else 1 end    
    251.   
    252. EXEC msdb..sp_add_jobschedule @job_name=@jobname,    
    253. @name = '时间安排',    
    254. @freq_type=@ftype , --每天,8 每周,16 每月    
    255. @freq_interval=1, --重复执行次数    
    256. @freq_subday_type=@fstype, --是否重复执行    
    257. @freq_subday_interval=@fsinterval, --重复周期    
    258. @freq_recurrence_factor=@ffactor,    
    259. @active_start_time=@time --下午17:00:00分执行    
    260.   
    261. go    
    262.   
    263. /*--应用案例--备份方案:   
    264. 完整备份(每个星期天一次)+差异备份(每天备份一次)+日志备份(每2小时备份一次)   
    265.  
    266. 调用上面的存储过程来实现   
    267. --*/    
    268.   
    269. declare @sql varchar(8000)    
    270. --完整备份(每个星期天一次)    
    271. set @sql='exec p_backupdb @dbname=''要备份的数据库名'''    
    272. exec p_createjob @jobname='每周备份',@sql,@freqtype='week'    
    273.   
    274. --差异备份(每天备份一次)    
    275. set @sql='exec p_backupdb @dbname=''要备份的数据库名'',@bktype='DF''    
    276. exec p_createjob @jobname='每天差异备份',@sql,@freqtype='day'    
    277.   
    278. --日志备份(每2小时备份一次)    
    279. set @sql='exec p_backupdb @dbname=''要备份的数据库名'',@bktype='LOG''    
    280. exec p_createjob @jobname='每2小时日志备份',@sql,@freqtype='day',@fsinterval=2    
    281.   
    282. /*--应用案例2   
    283.  
    284. 生产数据核心库:PRODUCE   
    285.  
    286. 备份方案如下:   
    287. 1.设置三个作业,分别对PRODUCE库进行每日备份,每周备份,每月备份   
    288. 2.新建三个新库,分别命名为:每日备份,每周备份,每月备份   
    289. 3.建立三个作业,分别把三个备份库还原到以上的三个新库。   
    290.  
    291. 目的:当用户在produce库中有任何的数据丢失时,均可以从上面的三个备份库中导入相应的TABLE数据。   
    292. --*/    
    293.   
    294. declare @sql varchar(8000)    
    295.   
    296. --1.建立每月备份和生成月备份数据库的作业,每月每1天下午16:40分进行:    
    297. set @sql='    
    298. declare @path nvarchar(260),@fname nvarchar(100)    
    299. set @fname=''PRODUCE_''+convert(varchar(10),getdate(),112)+''_m.bak''    
    300. set @path=dbo.f_getdbpath(null)+@fname    
    301.   
    302. --备份    
    303. exec p_backupdb @dbname=''PRODUCE'',@bkfname=@fname    
    304.   
    305. --根据备份生成每月新库    
    306. exec p_RestoreDb @bkfile=@path,@dbname=''PRODUCE_月''    
    307.   
    308. --为周数据库恢复准备基础数据库    
    309. exec p_RestoreDb @bkfile=@path,@dbname=''PRODUCE_周'',@retype=''DBNOR''    
    310.   
    311. --为日数据库恢复准备基础数据库    
    312. exec p_RestoreDb @bkfile=@path,@dbname=''PRODUCE_日'',@retype=''DBNOR''    
    313. '    
    314. exec p_createjob @jobname='每月备份',@sql,@freqtype='month',@time=164000    
    315.   
    316. --2.建立每周差异备份和生成周备份数据库的作业,每周日下午17:00分进行:    
    317. set @sql='    
    318. declare @path nvarchar(260),@fname nvarchar(100)    
    319. set @fname=''PRODUCE_''+convert(varchar(10),getdate(),112)+''_w.bak''    
    320. set @path=dbo.f_getdbpath(null)+@fname    
    321.   
    322. --差异备份    
    323. exec p_backupdb @dbname=''PRODUCE'',@bkfname=@fname,@bktype=''DF''    
    324.   
    325. --差异恢复周数据库    
    326. exec p_backupdb @bkfile=@path,@dbname=''PRODUCE_周'',@retype=''DF''    
    327. '    
    328. exec p_createjob @jobname='每周差异备份',@sql,@freqtype='week',@time=170000    
    329.   
    330. --3.建立每日日志备份和生成日备份数据库的作业,每周日下午17:15分进行:    
    331. set @sql='    
    332. declare @path nvarchar(260),@fname nvarchar(100)    
    333. set @fname=''PRODUCE_''+convert(varchar(10),getdate(),112)+''_l.bak''    
    334. set @path=dbo.f_getdbpath(null)+@fname    
    335.   
    336. --日志备份    
    337. exec p_backupdb @dbname=''PRODUCE'',@bkfname=@fname,@bktype=''LOG''    
    338.   
    339. --日志恢复日数据库    
    340. exec p_backupdb @bkfile=@path,@dbname=''PRODUCE_日'',@retype=''LOG''    
    341. '    
    342. exec p_createjob @jobname='每周差异备份',@sql,@freqtype='day',@time=171500  
    版权说明

      如果标题未标有<转载、转>等字则属于作者原创,欢迎转载,其版权归作者和博客园共有。
      作      者:温景良
      文章出处:http://wenjl520.cnblogs.com/  或  http://www.cnblogs.com/

  • 相关阅读:
    【Alpha】Scrum Meeting 10
    【Alpha】Scrum Meeting 9
    【Alpha】Scrum Meeting 8
    【Alpha】Scrum Meeting 7
    团队项目拆解
    【Alpha】Scrum Meeting 6
    【Alpha】Scrum Meeting 5
    servlet转发与重定向区别
    servlet中request和response
    Java Web之Servlet中response、request乱码问题解决
  • 原文地址:https://www.cnblogs.com/wenjl520/p/1352319.html
Copyright © 2020-2023  润新知