3

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

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

  1. 使用 SQL 2008 创建新服务器
  2. 关闭旧服务器上的 SQL 服务并将数据库复制到新服务器
  3. 关闭旧服务器并将新服务器重命名为与旧服务器相同的名称。
  4. 附上50个数据库

有没有使用 t-sql 将 50 个数据库附加到新服务器的快速方法?

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

4

2 回答 2

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 实用程序及其所有参数的更多信息。

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在这里假设-根据需要进行调整),就可以使用此方法。

于 2012-05-31T14:07:32.393 回答
2

为了重申我的评论,我建议使用备份/恢复方法,而不是分离/附加方法(我的原因在此处此处概述)。

虽然我喜欢@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 服务器上复制并运行恢复命令。

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

于 2012-05-31T14:46:33.120 回答