/*--备份指定表到另一数据库 备份指定数据库中的指定表列表到一个新的数据库--邹建 2003.12--*//*--调用示例
--备份数据当前数据库的所有内容
exec p_backupdatabase

--备份当前数据库的指定表
exec p_backupdatabase @tblist='tb,tb1,tb2'
--*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_BackupDataBase]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[p_BackupDataBase]
GOCREATE PROCEDURE p_BackupDataBase
@s_dbname sysname='', --要备份的数据库名,如果不指定,则备份当前数据库
@d_dbname sysname='', --备份生成的数据库名,如果不指定,则为:@s_dbname+'_bak'
@tblist varchar(8000)='' --要备份的表名列表,如果不指定,则表示所有用户表
AS
declare @sql varchar(8000),@err_msg varchar(1000)--参数检测
if isnull(@s_dbname,'')='' set @s_dbname=db_name()
if isnull(@d_dbname,'')='' set @d_dbname=@s_dbname+'_bak'
if exists(select 1 from master..sysdatabases where name=@d_dbname)
begin
set @err_msg='备份的数据库 ['+@d_dbname+'] 已经存在!'
goto lb_exit
end
if not exists(select 1 from master..sysdatabases where name=@s_dbname)
begin
set @err_msg='要备份的数据库 ['+@d_dbname+'] 不存在!'
goto lb_exit
end--创建备份的数据库
set @sql='create database ['+@d_dbname+']'
exec(@sql)--备份表
declare @tbname sysname
set @sql='declare tb cursor for
select name from ['+@s_dbname+']..sysobjects 
where status>0 and xtype=''U'''
+case isnull(@tblist,'') when '' then '' 
else ' and name in('''+replace(@tblist,',',''',''')+''')' end
exec(@sql)
open tb
fetch next from tb into @tbname
while @@fetch_status=0
begin
set @sql='select * into ['+@d_dbname+']..['+@tbname
+'] from ['+@s_dbname+']..['+@tbname+']'
exec(@sql)
fetch next from tb into @tbname
end
close tb
deallocate tblb_exit:
if @err_msg<>'' raiserror(@err_msg,1,16)
go

解决方案 »

  1.   

    如果有文件组,则备份文件组和恢复就可以.--以下代码简单地演示了如何进行文件组的备份及还原(在还原时,模拟了丢失第二次文件组备份文件的情况)。
    --创建测试数据库
    CREATE DATABASE db
    ON PRIMARY(
    NAME='db_data',
    FILENAME= 'c:\db_data.mdf'),
    FILEGROUP db_fg1(
    NAME = 'db_fg1_data',
    FILENAME = 'c:\db_fg1_data.ndf'),
    FILEGROUP db_fg2(
    NAME = 'db_fg2_data',
    FILENAME = 'c:\db_fg2_data.ndf')
    LOG ON(
    NAME='db_log',
    FILENAME ='c:\db.ldf')
    GO--在文件组db_fg1上创建表,并单独创建该文件组的备份
    CREATE TABLE db.dbo.tb(id int) ON db_fg1
    BACKUP DATABASE db FILEGROUP='db_fg1' TO DISK='c:\db_fg1.bak' WITH FORMAT
    GO在其他文件组上创建表 
    CREATE TABLE db.dbo.ta(id int) ON [PRIMARY]
    CREATE TABLE db.dbo.tc(id int) ON db_fg2
    INSERT db.dbo.tb SELECT id FROM sysobjects
    --备份每个文件组,并且备份事务日志
    BACKUP DATABASE db FILEGROUP='PRIMARY' TO DISK='c:\db_primary.bak' WITH FORMAT
    BACKUP DATABASE db FILEGROUP='db_fg1' TO DISK='c:\db_fg1_new.bak' WITH FORMAT
    BACKUP DATABASE db FILEGROUP='db_fg2' TO DISK='c:\db_fg2.bak' WITH FORMAT
    BACKUP LOG db TO DISK='c:\db_log.bak' WITH FORMAT
    GO--删除数据库
    DROP DATABASE db
    GO--从文件组备份中恢复数据
    RESTORE DATABASE db FILEGROUP='PRIMARY' FROM DISK='c:\db_primary.bak' WITH NORECOVERY,REPLACE
    RESTORE DATABASE db FILEGROUP='db_fg1' FROM DISK='c:\db_fg1.bak' WITH NORECOVERY
    RESTORE DATABASE db FILEGROUP='db_fg2' FROM DISK='c:\db_fg2.bak' WITH NORECOVERY
    RESTORE LOG db FROM DISK='c:\db_log.bak' WITH RECOVERY
    SELECT COUNT(*) FROM db.dbo.tb
    GO--删除测试数据库
    DROP DATABASE db
      

  2.   

    --创建测试数据库
    CREATE DATABASE Db
    GO--对数据库进行备份
    BACKUP DATABASE Db TO DISK='c:\db.bak' WITH FORMAT
    GO--创建测试表
    CREATE TABLE Db.dbo.TB_test(ID int)--延时1秒钟,再进行后面的操作(这是由于SQL Server的时间精度最大为百分之三秒,不延时的话,可能会导致还原到时间点的操作失败)
    WAITFOR DELAY '00:00:01'
    GO--假设我们现在误操作删除了 Db.dbo.TB_test 这个表
    DROP TABLE Db.dbo.TB_test--保存删除表的时间
    SELECT dt=GETDATE() INTO #
    GO--在删除操作后,发现不应该删除表 Db.dbo.TB_test--下面演示了如何恢复这个误删除的表 Db.dbo.TB_test--首先,备份事务日志(使用事务日志才能还原到指定的时间点)
    BACKUP LOG Db TO DISK='c:\db_log.bak' WITH FORMAT
    GO--接下来,我们要先还原完全备份(还原日志必须在还原完全备份的基础上进行)
    RESTORE DATABASE Db FROM DISK='c:\db.bak' WITH REPLACE,NORECOVERY
    GO--将事务日志还原到删除操作前(这里的时间对应上面的删除时间,并比删除时间略早
    DECLARE @dt datetime
    SELECT @dt=DATEADD(ms,-20,dt) FROM #  --获取比表被删除的时间略早的时间
    RESTORE LOG Db FROM DISK='c:\db_log.bak' WITH RECOVERY,STOPAT=@dt
    GO--查询一下,看表是否恢复
    SELECT * FROM Db.dbo.TB_test/*--结果:
    ID          
    ----------- (所影响的行数为 0 行)
    --*/--测试成功
    GO--最后删除我们做的测试环境
    DROP DATABASE Db
    DROP TABLE #
      

  3.   

    USE master--创建并完全备份数据库
    CREATE DATABASE db
    BACKUP DATABASE db TO DISK='c:\db.bak' WITH FORMAT
    GO--标记事务处理
    BEGIN TRANSACTION Tran1 WITH MARKCREATE TABLE db.dbo.tb(id int)COMMIT TRAN Tran1--事务完成后插入数据
    INSERT db.dbo.tb SELECT id FROM sysobjects
    GO--还原数据到事务标记 Tran1 前
    BACKUP LOG db TO DISK='c:\db_log.bak' WITH FORMAT
    DROP DATABASE db
    RESTORE DATABASE db FROM DISK='c:\db.bak' WITH NORECOVERY
    RESTORE LOG db FROM DISK='c:\db_log.bak' WITH STOPBEFOREMARK='Tran1'
    SELECT COUNT(*) FROM db.dbo.tb
    /*--事务标记 Tran1 前没有创建表,所以会收到错误信息
    对象名 'db.dbo.tb' 无效。
    --*/
    GO--还原数据库到事务标记 Tran1 后
    DROP DATABASE db
    RESTORE DATABASE db FROM DISK='c:\db.bak' WITH NORECOVERY
    RESTORE LOG db FROM DISK='c:\db_log.bak' WITH STOPATMARK='Tran1'
    SELECT COUNT(*) FROM db.dbo.tb
    /*--结果
    ----------- 
    0(所影响的行数为 1 行)
    --*/
    GO--删除测试
    DROP DATABASE db
      

  4.   

    USE master--创建数据库
    CREATE DATABASE db
    ON PRIMARY(
    NAME='db_data',
    FILENAME= 'c:\db_data.mdf'),
    FILEGROUP db_fg1(
    NAME = 'db_fg1_data',
    FILENAME = 'c:\db_fg1_data.ndf'),
    FILEGROUP db_fg2(
    NAME = 'db_fg2_data',
    FILENAME = 'c:\db_fg2_data.ndf')
    LOG ON(
    NAME='db_log',
    FILENAME ='c:\db.ldf')
    GO--创建表
    CREATE TABLE db.dbo.ta(id int) ON [PRIMARY]
    CREATE TABLE db.dbo.tb(id int) ON db_fg1
    CREATE TABLE db.dbo.tc(id int) ON db_fg2
    INSERT db.dbo.tb SELECT id FROM sysobjects
    GO
    --做文件组备份
    BACKUP DATABASE db FILEGROUP='db_fg1' TO DISK='c:\db_fg1.bak' WITH FORMAT--备份后,再做数据处理
    INSERT db.dbo.ta SELECT id FROM sysobjects
    GO/*--下面演示了破坏数据文件的处理,这些操作在操作系统中进行
    1. 停止SQL Server服务(msqlserver服务)
    2. 删除文件 c:\db_fg1_data.ndf (模拟破坏)
    3. 重新SQL Server服务,此时数据库DB置疑
    --*/
    GO--下面演示了如何恢复数据
    --首先要备份当前日志
    BACKUP LOG db TO DISK='c:\db_log.bak' WITH FORMAT,NO_TRUNCATE
    --利用文件组备份恢复破坏的文件
    RESTORE DATABASE db FILEGROUP='db_fg1' FROM DISK='c:\db_fg1.bak' WITH NORECOVERY
    --还原到日志点
    RESTORE LOG db FROM DISK='c:\db_log.bak' WITH RECOVERY
    --显示已经恢复的数据
    SELECT COUNT(*) FROM db.dbo.tb
    SELECT COUNT(*) FROM db.dbo.ta
    GO--删除测试
    DROP DATABASE db
      

  5.   

    /*--备份数据库,并按日期生成备份目录--邹建 2003.10--*//*--调用示例--备份当前数据库
    exec p_backupdb --*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_backupdb]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[p_backupdb]
    GOcreate proc p_backupdb
    @dbname sysname='', --要备份的数据库名称,不指定则备份当前数据库
    @bkfname nvarchar(260)='', --备份文件名,文件名中可以用\DBNAME\代表数据库名,\DATE\代表日期,\TIME\代表时间
    @bkpath nvarchar(260)='c:\' --备份文件的存放目录,在该目录下创建每天备份的目录
    as
    declare @sql varchar(8000)
    if isnull(@dbname,'')='' set @dbname=db_name()
    if right(@bkpath,1)<>'\' set @bkpath=@bkpath+'\'
    set @bkpath=@bkpath+convert(varchar,getdate(),112)+'\'

    --创建目录
    set @sql='md '+@bkpath
    exec master..xp_cmdshell @sql,no_output

    --备份处理
    if isnull(@bkfname,'')='' set @bkfname='\DBNAME\_\DATE\.BAK'
    set @bkfname=replace(replace(replace(@bkfname,'\DBNAME\',@dbname)
    ,'\DATE\',convert(varchar,getdate(),112))
    ,'\TIME\',replace(convert(varchar,getdate(),108),':',''))
    set @sql='backup database '+@dbname
    +' to disk='''+@bkpath+@bkfname+''''
    exec(@sql)
    go
      

  6.   

    以下工具可生成表数据和表结构
    http://download.csdn.net/source/297393
      

  7.   


    --恢复指定目录下的指定数据库
    exec p_RestoreDb @bkpath='c:\',@bkfile='客户资料,xzkh_new'
    --*/
    create proc p_RestoreDb
    @bkpath nvarchar(1000)='',  --定义备份文件的存放目录,默认为SQL的备份目录
    @bkfile nvarchar(4000)='', --定义要恢复的备份文件名,不含扩展名
    @dbpath nvarchar(260)='', --恢复后的数据库存放目录,不指定则为SQL的默认数据目录
    @overexist bit=1,        --是否覆盖已经存在的数据库,仅@retype为'DB'/'DBNOR'是有效
    @killuser bit=1     --是否关闭用户使用进程,仅@overexist=1时有效
    as
    declare @sql varchar(8000),@dbname sysnameif isnull(@bkpath,'')=''
    begin
    select @bkpath=rtrim(reverse(filename)) from master..sysfiles where name='master'
    select @bkpath=substring(@bkpath,charindex('\',@bkpath)+1,4000)
    ,@bkpath=reverse(substring(@bkpath,charindex('\',@bkpath),4000))+'BACKUP\'
    end
    else if right(@bkpath,1)<>'\' set @bkpath=@bkpath+'\'--得到恢复后的数据库存放目录
    if isnull(@dbpath,'')=''
    begin
    select @dbpath=rtrim(reverse(filename)) from master..sysfiles where name='master'
    select @dbpath=reverse(substring(@dbpath,charindex('\',@dbpath),4000))
    end
    else if right(@dbpath,1)<>'\' set @dbpath=@dbpath+'\'--得到指定目录下的所有备份文件
    create table #t(fname varchar(260),depth int,isf bit)
    insert into #t exec master..xp_dirtree @bkpath,1,1if isnull(@bkfile,'')=''
    declare tb cursor local for select fn=left(fname,patindex('%.bak',fname)-1) from #t
    where isf=1 and fname like '%.bak'  --取.bak文件
    else
    begin
    set @bkfile=','+replace(@bkfile,',','.bak,')+'.bak,'
    declare tb cursor local for select fn=left(fname,patindex('%.bak',fname)-1) from #t
    where isf=1 and fname like '%.bak' and @bkfile like '%,'+fname+',%'
    end--恢复数据库处理
    open tb
    fetch next from tb into @dbname
    while @@fetch_status=0
    begin
    --生成数据库恢复语句
    set @sql='restore database ['+@dbname
    +'] from disk='''+@bkpath+@dbname+'.bak'''
    +' with RECOVERY'
    +case when @overexist=1 then ',replace' else '' end --添加移动逻辑文件的处理
    --从备份文件中获取逻辑文件名
    declare @lfn nvarchar(128),@tp char(1),@i int --创建临时表,保存获取的信息
    create table #tb(ln nvarchar(128),pn nvarchar(260),tp char(1),fgn nvarchar(128),sz numeric(20,0),Msz numeric(20,0))
    --从备份文件中获取信息
    insert into #tb exec('restore filelistonly from disk='''+@bkpath+@dbname+'.bak''')
    declare #f cursor local for select ln,tp from #tb order by tp
    open #f
    fetch next from #f into @lfn,@tp
    set @i=0
    while @@fetch_status=0
    begin
    select @sql=@sql+',move '''+@lfn+''' to '''+@dbpath+@dbname+cast(@i as varchar)
    +case @tp when 'D' then '.mdf''' else '.ldf''' end
    ,@i=@i+1
    fetch next from #f into @lfn,@tp
    end
    close #f
    deallocate #f
    drop table #tb --关闭用户进程处理
    if @overexist=1 and @killuser=1
    begin
    declare hCForEach cursor for
    select s='kill '+cast(spid as varchar) from master..sysprocesses 
    where dbid=db_id(@dbname)
    exec sp_msforeach_worker '?'
    end --恢复数据库
    exec(@sql)
    fetch next from tb into @dbname
    end
    close tb
    deallocate tb
    go
      

  8.   

    在数据库
    用restore是控制不了还原某几个表的,只有用生成数据脚本和导入导出
      

  9.   

    我觉得好复杂哦我一时还理解不了这么多是数据库因为他们的某个操作, 数据有问题了本来想要restore整个database, 但现在又改主意要restore某个表就可以了我以为会比restore整个database更简单的...没想到这么复杂真的只能这样吗? 没有更简单的吗?
      

  10.   

    不复杂啊..
    先用restore还原整个数据库.然后把它当成一个临时数据库..
    然后再把这数据库里的某些表导入/导出.可以使用DTS或roy_88提供的工具..
    然后再把这个临时数据库删除即可.
      

  11.   

    最简单的就是
    BACKUP DATABASE DBname to DISK='PATH\%.BAK'
    restore DATABASE DBname FROM DISK='PATH\%.BAK'
      

  12.   

    正在restore还碰到个问题restore的时候说 database is in use...试过启用single-user, 但是还是因为in use, 不能查看database的属性, 更不能restore...我们用了sa登陆, 还是说它in use我们几乎已经通知了所有的人disconnect, 但还是in use...要怎么查看database是谁在使用怎么踢掉他? 谢谢
      

  13.   

    谢谢, 现在都好了我把这个database take offline, 然后bring online
    那个连着数据库又sleeping状态的用户就不连接了呵呵thanks again