批量附加数据库

背景

最近我们在替换生产环境的数据库服务器的时候,因该实例下库比较多,差不多有近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

参考

sp_attach_db

后记

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

时间: 2024-10-07 13:41:00

批量附加数据库的相关文章

SQL Server 分离与附加数据库

分离数据库 1.选中要分离的数据库,鼠标右键选择任务->分离,在弹出框内点击确定即可. 附加数据库 1.在SSMS对象资源管理器中,鼠标右键数据库菜单,选择附加. 2.在弹出框内,点击添加按钮,然后找到数据库主文件所在地,点击确定按钮即可.

4-02分离与附加数据库

分离与附加数据库的方式以及步骤: 在视图下分离与附加数据库: 第一步: 点击数据库,右击附加. 第二步: 弹出这个窗口,然后点击添加. 第三步: 就可以把磁盘里面的数据库文件附加到Sql Sever中. 用存储过程分离与附加数据库: EXEC sp_detach_db @dbname=E_Market --分离数据库 EXEC sp_detach_db @dbname=E_Market @filename1=''H:\project\E_Market_data.mdf @filename1=''

sql server 附加数据库的时候出现“无法为此请求检索数据”

我重装电脑前建立的数据库,现在不能附加了 解决方案 对那个数据库文件和数据库日志文件(一定要两个),分别右击属性,在中间个“安全”中 然后  就是点确定就行了,再试试附加数据库?!!!成了!

SQL Server附加数据库出现错误5123的正确解决方法

SQL Server附加数据库出现错误5123的正确解决方法 因为自己有一本基于SQL Server 2005的数据库教程,里边使用的示例数据库是AdventureWorks for SQL Server 2005,而我的机子上装的是SQL Server 2008,示例数据库是AdventureWorks for SQL Server 2008.起初我以为示例数据库AdventureWorks for SQL Server 2005 与AdventureWorks for SQL Server

SQL Server 2008 R2 附加数据库 “尝试打开或创建物理文件 拒绝访问”的解决办法

其实是来自一篇SQL Server 2005同样错误的帖子,不过试了在SQL Server 2008 R2下面也有效,记录一下. 解决方法: 在所有程序—Microsoft SQL Server 2008 R2—配置工具—SQL Server 配置管理器,点击"SQL Server 服务",右边会显示正在运行的服务,以及对应的用户,右击SQL Server (MSSQLSERVER),选择“属性”,把内置帐户选择为"Local System",点击重新启动就OK了.

Win7 sql2005附加数据库失败 错误5120

错误信息如下: 标题: Microsoft SQL Server Management Studio Express------------------------------ 附加数据库 对于 服务器“TITANIC-PC/SQLEXPRESS”失败. (Microsoft.SqlServer.Express.Smo) 有关帮助信息,请单击: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=9.00.30

批量创建数据库和批量数据恢复

近期公司有一个数据库需要迁移,但是里面创建的数据库比较多,我们采取脚本将库单独备份,然后上传到另一台主机,新建数据库,然后恢复数据库.将自己写的几个小脚本粘贴到此, 分库压缩备份 #/bin/sh #version 0.1 MYUSER=mysqlback [email protected] #SOCKET=/data/3306/mysql.sock MYLOGIN="mysql -u$MYUSER -p$MYPASS " MYDUMP="mysqldump -u$MYUSE

修改、分离和附加数据库

一.修改数据库(增大及缩小) 方法1.可以直接数据库属性修改.但是必须注意,缩小数据库的size,需要使用到任务--收缩. 方法2.为了避免系统盲目的切除内存,最好使用命令修改: ALTER DATABASE PAY MODIFY name=payment,size=2MB 二.分离和附加数据库 1.分离数据库:源文件将保留,用于在文件使用过程中复制文件等操作.分离数据库不会删除数据库文件和事务日志,只是在分离之后不会显示在数据库列表中了. 注意:在下列状态下不可以进行数据库的分离 (1)活动状

C# 自动部署之附加数据库

看着别人的网站能够自动安装,数据库自动附加,觉得很神奇很向往,但是始终米有去手动实践. 网上找了下资料,发现实现起来其实很简单 直接code private bool Attachdb() { //sMDBFile 为mdf文件路径 //sLog 为ldf文件路径 string sMDBFile = Server.MapPath("/data/DBTest.mdf"); string sLog = Server.MapPath("/data/DBTest_log.ldf&qu