使用T-SQL附加多个数据库

时间:2012-05-31 14:00:50

标签: sql sql-server-2008

我们正在将我们的一台服务器从SQL Server 2005迁移到SQL Server 2008。 该服务器上有大约50个小型数据库。

我们采取的迁移路径如下:

  1. 使用SQL 2008创建新服务器
  2. 关闭旧服务器上的SQL服务并将数据库复制到新服务器
  3. 关闭旧服务器并将新服务器重命名为旧服务器。
  4. 附上50个数据库
  5. 是否有使用t-sql将50个数据库附加到新服务器的快速方法?

    所有数据文件都将位于E:\ DATA,而事务日志将位于E:\ TLOG

2 个答案:

答案 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命令。

您还需要更新密钥表的统计信息,否则当您的性能下降时,您可能会遇到一些严重的问题,因为新服务器上的计划缓存已准备就绪......