批量附加数据库

Posted jil.wen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了批量附加数据库相关的知识,希望对你有一定的参考价值。

背景

最近我们在替换生产环境的数据库服务器的时候,因该实例下库比较多,差不多有近200个库,加上维护窗口的时间有限,所以我们有必要写段脚本快速批量附加所有的库,并确保所有的库都附加成功。当前的情况是所有的库名都是唯一且不存在库名相似的情形,如 db_1  和 db_12 不存在这种库名相似的情况。

环境

Microsoft SQL Server 2012 (SP3-CU2) (KB3137746) - 11.0.6523.0 (X64) 
Mar  2 2016 21:29:16 
Copyright (c) Microsoft Corporation
Web Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
 

过程

第一步 在旧生产环境上执行,获取所有正式在用的库名信息
为了确保需附加的库名,以及为后续附加成功之后检验核对是否存在数据库文件缺少或未成功附加。提前在旧的生产运行如下代码,并且成功导出结构和数据,再拷贝导出的文件至新的服务器上执行。
 1 ---读取源数据库信息 先用从源数据库读取数据库信息
 2 use master
 3 IF OBJECT_ID(sourcetable) IS NOT NULL
 4     DROP TABLE sourcetable;
 5 SELECT name,
 6     database_id,
 7     0 AS okflag
 8 INTO sourcetable
 9 FROM sys.databases
10 WHERE database_id > 4
11 ORDER BY name;

技术分享

技术分享
技术分享
技术分享
技术分享
技术分享
技术分享
技术分享 
将导出至桌面的wen.sql文件拷至新的服务器上,并在ssms中成功执行。
第二步  生成批量附加代码并执行

默认场景是数据库文件已全部拷贝至新的生产环境,也不存在权限限制访问之类的问题。在新的生产环境执行如下代码

  1 /********
  2 Just for a quick review, xp_dirtree has three parameters:
  3 1 directory - This is the directory you pass when you call the stored procedure; for example ‘D:\Backup‘.
  4 2 depth  - This tells the stored procedure how many subfolder levels to display.  The default of 0 will display all subfolders.
  5 3 isfile - This will either display files as well as each folder.  The default of 0 will not display any files.
  6 *********/
  7 ---读取数据库文件
  8 IF OBJECT_ID(tempdb..#DirectoryTree) IS NOT NULL
  9     DROP TABLE #DirectoryTree;
 10 CREATE TABLE #DirectoryTree
 11 (
 12     id INT IDENTITY(1, 1),
 13     subdirectory NVARCHAR(512),
 14     depth INT,
 15     isfile BIT
 16 );
 17 INSERT #DirectoryTree
 18 (   subdirectory,
 19     depth,
 20     isfile
 21 )
 22 EXEC master..xp_dirtree D:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA,  --数据库文件存放路径,如有多个路径类似。
 23     1,
 24     1;
 25 --SELECT *
 26 --FROM #DirectoryTree;
 27 ---生成附加代码
 28 DECLARE @file VARCHAR(MAX);
 29 SET @file
 30     = D:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\; ---具体数据文件存放的路径
 31 DECLARE @name VARCHAR(500),  --数据库名
 32     @database_id INT,        --数据库ID
 33     @temp VARCHAR(MAX);      --存放附加代码
 34 SET @temp = ‘‘;
 35 DECLARE c_wen CURSOR FAST_FORWARD
 36 FOR
 37 SELECT name,
 38     database_id
 39 FROM sourcetable
 40 ORDER BY name;
 41 OPEN c_wen;
 42 FETCH NEXT FROM c_wen
 43 INTO @name,
 44     @database_id;
 45 WHILE @@FETCH_STATUS = 0
 46 BEGIN
 47     DECLARE @id INT,        --存放附加文件个数值
 48         @temp_id INT,       --存放最大附加文件个数值
 49         @subdirectory VARCHAR(MAX), --待附加的文件名
 50         @t VARCHAR(MAX);    --存放单个库附加的代码
 51     SET @t = ‘‘;
 52     SELECT @id = COUNT(1)
 53     FROM #DirectoryTree
 54     WHERE subdirectory LIKE % + @name + %;
 55     SELECT @temp_id = COUNT(1)
 56     FROM #DirectoryTree
 57     WHERE subdirectory LIKE % + @name + %;
 58     SELECT ROW_NUMBER() OVER (ORDER BY subdirectory) id,
 59         subdirectory
 60     FROM #DirectoryTree
 61     WHERE subdirectory LIKE % + @name + %;
 62     WHILE (@id) >= 1       --存在多个需附加的文件
 63     BEGIN
 64         SELECT @subdirectory = subdirectory
 65         FROM
 66         (
 67             SELECT ROW_NUMBER() OVER (ORDER BY subdirectory) id,
 68                 subdirectory
 69             FROM #DirectoryTree
 70             WHERE subdirectory LIKE % + @name + %
 71         ) a
 72         WHERE a.id = @id;
 73         SELECT @t
 74             = @t + ‘‘‘‘ + @file + @subdirectory + ‘‘‘‘
 75               + CASE
 76                     WHEN @id > 1 THEN
 77                         ,
 78                     ELSE
 79                         ;  + CHAR(10) + CHAR(13) + GO
 80                 END + CHAR(10) + CHAR(13);
 81         SET @id = @id - 1;
 82     END;
 83     IF (
 84            @temp_id = 0    --只有库名,不存在附加文件
 85        )
 86     BEGIN
 87         SELECT @t = ‘‘;
 88     END;
 89     ELSE
 90     BEGIN
 91         SELECT @t
 92             = EXEC sys.sp_attach_db  + ‘‘‘‘ + @name + ‘‘‘‘ + , + CHAR(10)
 93               + CHAR(13) + @t;
 94     END;
 95     FETCH NEXT FROM c_wen
 96     INTO @name,
 97         @database_id;
 98     SELECT @temp = @temp + @t;
 99 END;
100 SELECT @temp
101 FOR XML PATH(‘‘);
102 CLOSE c_wen;
103 DEALLOCATE c_wen;

技术分享

复制xml文件中批量附加代码在新窗口执行。
 
第三步  验证在新的生产环境执行
附加完毕需验证是否存在失败或遗漏的情况;
 1 use master
 2 --计算原来生产环境的库合计
 3 select count(1) from [dbo].[sourcetable]  
 4 ---缺失或失败的库名
 5 select 
 6      a.name 
 7 from [sourcetable] a  left join 
 8      sys.databases b 
 9      on a.name=b.name
10 where b.name is null

技术分享

参考 

后记

有兴趣的同学可以考虑使用PowerShell,如foreach折腾一下。

以上是关于批量附加数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何在屏幕方向更改时附加片段?

批量分离库代码实践

片段 MyFragment 未附加到 Activity

java.lang.IllegalStateException:片段未附加到活动

片段未附加到上下文

Android:将数据(附加)传递给片段