问题描述
:
一台服务器,联了好几个阵列,其实可以看作不同的逻辑驱动器,就假设为
c
盘,
d
盘,
e
盘
sql server 2000
程序装在了
c
盘,数据装在了
d
盘
现在阵列
d
需要撤走,我需要把原来
d
盘的数据库文件挪到
e
盘上,数据库有
100
多个,一个一个手动备份恢复时间不够,而且我不知道数据库文件的路径变了以后会有什么问题(我做了试验,服务起不起来了)。
我应该如何做
?
我试了一种办法,就是把
d
盘的所有数据库的数据文件和文件夹原封不动的拷贝到
e
盘,然后把
d
盘撤走,把
e
盘的盘符改为
d,
就可以了,但是总觉得属于歪招,所以想知道正规做法是怎么做的?
解决方法
:
最省事的方法还是所谓的改盘符歪招
.
这种方法也最节约时间
.
正常的方法就是备份
/
还原
(
不推荐
,
太慢
)
或者是
1
楼的分离
/
附加
,
如果只是变盘符
,
可以写自动化脚本
最歪的方法是改系统表
,
直接把系统表中记录的数据文件和日志文件目录改正确
.(
SQL Server 2005
已经无法修改系统表
,
所以定义这种方法是最歪的
)
改系统表方法的具体实现脚本
:
--
自动迁离的脚本
(
自动实现分离
+
复制文件
+
附加
)
--
注意根据需要修改下面的
--**
注释的部分
.
--
邹建
2006.07 (
引用请保留此信息
)
--
备份数目录信息和分离数据库
IF
OBJECT_ID('tempdb..#') IS NOT NULL
DROP TABLE #
CREATE
TABLE #(
DbName sysname,
Name sysname,
FileName nvarchar(260),
FilePath as LEFT(FileName, LEN(FileName) - CHARINDEX('/', REVERSE(FileName))))
EXEC
sp_msforeachdb N'
--**
如果是所有的用户数据库都要处理
,
则去掉下面两句的注释
,
并且注释掉后面的两行
--IF N''?'' IN(N''master'', N''model'', N''msdb'', N''tempdb'')
--RETURN --
只能处理用户数据库
--**
如果是处理指定的用户数据库
,
则保持现状
IF N''?'' NOT IN(N''HelloWorldDB'', N''AdventureWorks'')
RETURN --
只处理指定列表的数据库
USE [?]
INSERT #(DbName, Name, FileName)
SELECT DB_NAME(), name, RTRIM(filename) FROM sysfiles
USE master
EXEC sp_detach_db N''?''
'
--
复制数据库文件
DECLARE
@s nvarchar(4000), @D_Drive char(1)
SET
@D_Drive = 'D' --**
迁移到
E
盘
DECLARE
tb CURSOR LOCAL
FOR
SELECT
N'xcopy "' + FileName + '" "' + STUFF(FilePath, 1, 1, @D_Drive) + '/" /y'
FROM
#
OPEN
tb
FETCH
tb INTO @s
WHILE
@@FETCH_STATUS = 0
BEGIN
PRINT(@s)
EXEC master.dbo.xp_cmdshell @s
FETCH tb INTO @s
END
CLOSE
tb
DEALLOCATE
tb
--
附加数据库
DECLARE
@dbname sysname
DECLARE
tb CURSOR LOCAL
FOR
SELECT
DISTINCT
DbName
FROM
#
OPEN
tb
FETCH
tb INTO @dbname
WHILE
@@FETCH_STATUS = 0
BEGIN
SET @s = N'EXEC sp_attach_db ' + QUOTENAME(@dbname, N'''')
SELECT @s = @s + N',''' + STUFF(FileName, 1, 1, @D_Drive) + N''''
FROM #
WHERE DbName = @dbname
EXEC sp_executesql @s
FETCH tb INTO @dbname
END
CLOSE
tb
DEALLOCATE
tb