背景 最近我們在替換生產環境的資料庫伺服器的時候,因該實例下庫比較多,差不多有近200個庫,加上維護視窗的時間有限,所以我們有必要寫段腳本快速批量附加所有的庫,並確保所有的庫都附加成功。當前的情況是所有的庫名都是唯一且不存在庫名相似的情形,如 db_1 和 db_12 不存在這種庫名相似的情況。 環 ...
背景
最近我們在替換生產環境的資料庫伺服器的時候,因該實例下庫比較多,差不多有近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