MSSQL数据库通过脚本多库备份及还原,多库操作很方便

每次通过 Management Studio 的界面操作备份或还原数据库,对于单个数据库还好,要是一次要做多个。那就还是用脚本快些,下面有两段脚本分享一下。

====================================================================
备份
====================================================================

生成备份脚本的脚本

d:\databak\为存在目录

SELECT 'BACKUP DATABASE ' + name + ' TO  DISK = N''d:\databak\' + name + '.bak''
   WITH NOFORMAT, NOINIT,
   NAME = N''' + name + '-完整 数据库 备份'',
   SKIP, NOREWIND, NOUNLOAD,  STATS = 10'
FROM sys.databases
where database_id>4    -- 跳过系统库
order by database_id
go

执行后生成如下脚本,复制如下脚本将正式执行备份:

BACKUP DATABASE 
    DataBaseName TO  DISK = N'd:\databak\DataBaseName.bak'     
WITH NOFORMAT, 
NOINIT,     
    NAME = N'DataBaseName-完整 数据库 备份',     
SKIP, 
NOREWIND, 
NOUNLOAD,  
STATS = 10

====================================================================
还原
====================================================================

生成还原脚本的脚本

请先填写参数表:  

@源路径

@目标路径

数据库名列表

@是否执行(是否直接执行还原)

@是否删除(是否删除数据库及关闭连接,慎用!!!)

/**
Author:HRZhao;
Date:2015-03-24
Version: V3 2019-08-26
*/

USE master
GO
SET nocount on 
declare @srcPath varchar(500);
declare @tarPath varchar(500);
declare @是否执行 int;
declare @是否删除 int;

CREATE TABLE #DATABASE(
    id int identity(1,1),
    name varchar(255)
)
--参数表--可同时多个库-------------------------------------------
INSERT INTO #DATABASE(name)
SELECT 'DataBaseName0'
--UNION ALL SELECT 'DataBaseName1'
--UNION ALL SELECT 'DataBaseName2'
--UNION ALL SELECT 'DataBaseName3'
--UNION ALL SELECT 'DataBaseName4'
---路径----------------------------------------------
SET @是否执行 = 1;--是否直接执行,若否,只打印还原语句
SET @是否删除 = 0;--是否删除数据库及关闭连接 /*** 慎用!!! ***/
SET @srcPath = 'G:\DBDATA\';
SET @tarPath = 'G:\SQLData\SQL00\';
--参数表End---------------------------------------------------

DECLARE @newLine varchar(500);
SET @newLine =  CHAR(10) --+ CHAR(13);
DECLARE @dbName varchar(500);
DECLARE @fName varchar(500);

PRINT ' USE master'+@newLine+' GO';
-------------WHILE---------------------
DECLARE @I INT;
SELECT @I = MAX(id) FROM #DATABASE;
WHILE @I IS NOT NULL
BEGIN
    SELECT @dbName = name FROM #DATABASE WHERE id = @I;
    IF ISNULL(@dbName,'')<>''
    BEGIN
        CREATE TABLE #TABLE(
            LogicalName VARCHAR(255),
            PhysicalName VARCHAR(255),
            Type VARCHAR(255),
            FileGroupName VARCHAR(255),
            Size BIGINT,--NUMERIC
            MaxSize BIGINT,--NUMERIC
            FileId BIGINT,
            CreateLSN BIGINT,
            DropLSN BIGINT,
            UniqueId VARCHAR(255),
            ReadOnlyLSN BIGINT,
            ReadWriteLSN BIGINT,
            BackupSizeInBytes BIGINT,
            SourceBlockSize BIGINT,
            FileGroupId BIGINT,
            LogGroupGUID VARCHAR(255),--
            DifferentialBaseLSN VARCHAR(255),
            DifferentialBaseGUID VARCHAR(255),
            IsReadOnly BIGINT,
            IsPresent BIGINT,
            TDEThumbprint VARCHAR(255)
        )

        declare @sql varchar(1000);
        set @sql = 'RESTORE FILELISTONLY FROM DISK = N'''+@srcPath+@dbName+'.bak'''
        insert into #TABLE exec (@sql)
        
        declare @logicalName_d varchar(500);
        declare @logicalName_l varchar(500);
        --set @logicalName_d = 'MTNOH_AAA_Resource';
        --set @logicalName_l = 'MTNOH_AAA_Resource_log';
        SELECT @logicalName_d = LogicalName FROM #TABLE WHERE [Type] = 'D';
        SELECT @logicalName_l = LogicalName FROM #TABLE WHERE [Type] = 'L';

        set @logicalName_d = case when @logicalName_d IS NULL THEN @dbName ELSE @logicalName_d END;
        set @logicalName_l = case when @logicalName_l IS NULL THEN @dbName+'_log' ELSE @logicalName_l END;
        set @fName = @dbName + '.bak';

        create table #temp(
            dbName varchar(500),
            fName varchar(500),
            srcPath varchar(500),
            tarPath varchar(500)
        )
        
        DECLARE @RESULT varchar(8000);
        INSERT INTO #temp select @dbName,@fName,@srcPath,@tarPath;
        
        
        --删除进程
        IF @是否删除 = 1
        BEGIN
            DECLARE @delSql nvarchar(max) 
            DECLARE tb cursor local for 
            SELECT s=' KILL '+cast(spid as varchar) +';'
            FROM master..sysprocesses 
            WHERE dbid=db_id(@dbname) 
            
            SET @delSql = NULL;
            
            open tb 
            fetch next from tb into @delSql 
            while @@fetch_status=0 
            begin
                PRINT @delSql 
                IF @是否执行 = 1
                    EXEC(@delSql);
            fetch next from tb into @delSql 
            end 
            close tb 
            deallocate tb 
            
            IF  EXISTS (SELECT name FROM sys.databases WHERE name = @dbname)
            BEGIN
                SET @delSql = ' DROP DATABASE ['+@dbname+']';
                PRINT @delSql;
                IF @是否执行 = 1
                    EXEC(@delSql)  
            END
        END
        
        SELECT @RESULT =  @newLine 
            --+ CASE WHEN @是否执行 = 1 THEN '' ELSE 'USE master ' END
            + @newLine + ' RESTORE DATABASE ' +@dbName
            + @newLine +' FROM DISK = '''+@srcPath+fName+''''
            + @newLine + ' WITH MOVE '''+@logicalName_d+''' TO '''+tarPath+dbName+'.mdf'','
            + @newLine + ' MOVE '''+@logicalName_l+''' TO '''+tarPath+dbName+'_log.ldf'','
            + @newLine + ' STATS = 10, REPLACE '
            + @newLine + CASE WHEN @是否执行 = 1 THEN '' ELSE ' GO ' END
            from #temp;
            
        PRINT @RESULT;
        IF @是否执行 = 1
            EXEC(@RESULT);
        TRUNCATE TABLE #temp;
        DROP TABLE #temp;
        TRUNCATE TABLE #TABLE;
        drop table #TABLE;
    END
    DELETE #DATABASE WHERE id = @I;
    SELECT @I = MAX(id) FROM #DATABASE;
END

TRUNCATE TABLE #DATABASE
DROP TABLE #DATABASE;
SET nocount OFF
GO
View Code

 

posted on 2015-04-15 13:34  HRZhao  阅读(584)  评论(3)    收藏  举报

导航

ron17173@139.com