我们正在将我们的一台服务器从SQL Server 2005迁移到SQL Server 2008。 该服务器上有大约50个小型数据库。
我们采取的迁移路径如下:
是否有使用t-sql将50个数据库附加到新服务器的快速方法?
所有数据文件都将位于E:\ DATA,而事务日志将位于E:\ TLOG
答案 0 :(得分:5)
使用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 utility and all its parameters。
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
在这里 - 根据需要进行调整),这是有效的。
答案 1 :(得分:2)
要重新评论我的评论,我建议使用备份/恢复方法而不是分离/附加方法(my reasons are outlined here)。
虽然我喜欢@ marc_s的SQLCMD方法,但我更喜欢直接从元数据中提取这些东西。通过这种方式,我可以检查所有输出,复制并粘贴我想要批量执行的部分,而不是一次性执行。等等:
DECLARE @bl VARCHAR(512) = '\\fileshare\folder\'; -- 'backup location
SET NOCOUNT ON;
SELECT 'BACKUP DATABASE ' + QUOTENAME(name)
+ ' TO DISK = ''' + @bl + name + '.BAK'' WITH INIT;
ALTER DATABASE ' + QUOTENAME(name) + ' SET OFFLINE;'
FROM sys.databases WHERE database_id > 4 -- AND other filter criteria
SELECT 'RESTORE DATABASE ' + QUOTENAME(d.name) + ' FROM DISK=''' + @bl + d.name
+ '.BAK'' WITH ' + STUFF((SELECT ',MOVE ''' + f.name + '''
TO ''E:\DATA\' + f.name + '.mdf''' FROM master.sys.master_files AS f
WHERE f.database_id = d.database_id AND type_desc = 'ROWS'
FOR XML PATH('')), 1, 1, '')
+', '+ STUFF((SELECT ',MOVE ''' + f.name + ''' TO ''E:\TLOG\' + f.name + '.mdf'''
FROM master.sys.master_files AS f
WHERE f.database_id = d.database_id AND type_desc = 'LOG'
FOR XML PATH('')), 1, 1, '') + ';
ALTER DATABASE ' + QUOTENAME(d.name) + ' SET COMPATIBILITY_LEVEL = 100;'
FROM sys.databases AS d WHERE database_id > 4 -- AND other filter criteria
(这假设您只有数据/日志文件,没有文件流等,并且您可以从两个实例都可访问的公共位置备份/恢复。)
为了澄清,您将在2005服务器上生成两组命令,copy&在那里运行备份命令(并可能在之后立即将它们设置为脱机),然后复制&在2008服务器上运行restore命令。
您还需要更新密钥表的统计信息,否则当您的性能下降时,您可能会遇到一些严重的问题,因为新服务器上的计划缓存已准备就绪......