我们正在将我们的一台服务器从 SQL Server 2005 迁移到 SQL Server 2008。这台服务器上有大约 50 个小型数据库。
我们正在采取的迁移路径如下:
- 使用 SQL 2008 创建新服务器
- 关闭旧服务器上的 SQL 服务并将数据库复制到新服务器
- 关闭旧服务器并将新服务器重命名为与旧服务器相同的名称。
- 附上50个数据库
有没有使用 t-sql 将 50 个数据库附加到新服务器的快速方法?
所有数据文件都将位于 E:\DATA 并且事务日志将位于 E:\TLOG
我们正在将我们的一台服务器从 SQL Server 2005 迁移到 SQL Server 2008。这台服务器上有大约 50 个小型数据库。
我们正在采取的迁移路径如下:
有没有使用 t-sql 将 50 个数据库附加到新服务器的快速方法?
所有数据文件都将位于 E:\DATA 并且事务日志将位于 E:\TLOG
使用 SQLCMD 模式,您可以轻松编写以下脚本:
:setvar dbname YourDatabaseName
:setvar dbfile N'E:\DATA\YourDatabase.mdf'
:setvar logfile N'E:\TLOG\YourDatabase_log.ldf'
USE [master]
GO
CREATE DATABASE $(dbname) ON
( FILENAME = $(dbfile) ),
( FILENAME = $(logfile) )
FOR ATTACH
GO
这可以sqlcmd.exe
从命令行工作(你甚至可以从命令行提供变量的值dbname, dbfile, logfile
),或者如果你启用了它在 SQL Server Management Studio 中工作Tools > Options > Query Execution > by default, open new queries in SQLCMD mode
。
在 MSDN 上阅读有关SQLCMD 实用程序及其所有参数的更多信息。
PS:当然,这种启用了 SQLCMD 的脚本的方法也适用于 BACKUP/RESTORE 周期:-)(如 Aaron 推荐的那样)
PPS:如果您有良好的命名约定,并且数据文件始终是$(dbname).mdf
并且日志文件始终是$(dbname)_log.ldf
,您也可以使用这个缩短的 SQLCMD 脚本:
:setvar dbname YourDatabaseName
USE [master]
GO
CREATE DATABASE $(dbname) ON
( FILENAME = N'E:\DATA\$(dbfile).mdf' ),
( FILENAME = N'E:\TLOG\$(logfile)_log.ldf' )
FOR ATTACH
GO
然后从命令行调用它:
C:\> sqlcmd.exe -S yourserver -E -i attach.sql -v dbname=YourDb1
依此类推,对于需要重新附加的每个数据库一次。
PPPS:如果你想恢复备份,它只是稍微复杂一点:
:setvar dbname YourDatabaseName
USE [master]
GO
RESTORE DATABASE $(dbname)
FROM DISK = N'E:\Backup\$(dbname).bak'
WITH FILE = 1,
MOVE N'$(dbname)' TO N'E:\DATA\$(dbname).mdf',
MOVE N'$(dbname)_Log' TO N'E:\TLOG\$(dbname)_Log.ldf',
NOUNLOAD, REPLACE
GO
只要您将.bak
文件命名为与数据库名称相同的名称,并且将它们放在固定位置(我E:\Backup
在这里假设-根据需要进行调整),就可以使用此方法。
为了重申我的评论,我建议使用备份/恢复方法,而不是分离/附加方法(我的原因在此处和此处概述)。
虽然我喜欢@marc_s 的 SQLCMD 方法,但我更喜欢直接从元数据中提取这些内容。这样我可以检查所有输出,复制和粘贴我想要批量执行的部分,而不是一次全部执行,等等。比如:
SET NOCOUNT ON;
DECLARE @folder nvarchar(512) = N'\\fileshare\folder\'; -- 'backup location
SELECT N'BACKUP DATABASE ' + QUOTENAME(name)
+ N' TO DISK = N''' + @folder + name + N'.BAK'' WITH INIT;
ALTER DATABASE ' + QUOTENAME(name) + N' SET OFFLINE;'
FROM sys.databases
WHERE database_id > 4 -- AND other filter criteria
SELECT N'RESTORE DATABASE ' + QUOTENAME(d.name)
+ N' FROM DISK = N''' + @folder + d.name + N'.BAK'' WITH '
+ STUFF(
(SELECT N',
MOVE N''' + f.name + N''' TO ''E:\DATA\' + f.name + '.mdf'''
FROM master.sys.master_files AS f
WHERE f.database_id = d.database_id
AND type_desc = N'ROWS'
FOR XML PATH(''),
TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, N'')
+ N', ' + STUFF(
(SELECT N',
MOVE N''' + f.name + N''' TO N''E:\TLOG\' + f.name + N'.mdf'''
FROM master.sys.master_files AS f
WHERE f.database_id = d.database_id
AND type_desc = 'LOG'
FOR XML PATH(''),
TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, N'') + N';
ALTER DATABASE ' + QUOTENAME(d.name)
+ N' SET COMPATIBILITY_LEVEL = 100;'
FROM sys.databases AS d
WHERE database_id > 4; -- AND other filter criteria
(这假设您只有数据/日志文件,没有文件流等,并且您可以从两个实例都可访问的公共位置备份到/恢复。)
澄清一下,您将在 2005 服务器上生成两组命令,复制并在那里运行备份命令(然后可能立即将它们设置为脱机),然后在 2008 服务器上复制并运行恢复命令。
您还需要更新关键表的统计信息,否则当新服务器上的计划缓存准备就绪时,当您的性能下降时,您可能会遇到一些严重的问题......