คุณสามารถใช้ Alter ฐานข้อมูลแก้ไขไฟล์หรือแยก / แนบวิธีการ
หมายเหตุ: ทั้งคู่จะต้องใช้เวลาหยุดทำงานบางอย่างดังนั้นจึงต้องทำในช่วงเวลาการบำรุงรักษา
สมมติว่าคุณมีโครงสร้างไดเรกทอรีเดียวกันในไดรฟ์ใหม่เช่น C: \ data \ และ D: \ Data
- การใช้ฐานข้อมูล Alter ด้วยวิธีการแก้ไข (ที่ต้องการ)
SET NOCOUNT ON
DECLARE @datafile VARCHAR(255)
,@logfile VARCHAR(255)
,@dbid TINYINT
,@SQLText VARCHAR(max)
,@dbname VARCHAR(255)
,@sqltext1 VARCHAR(max)
,@SQLText2 VARCHAR(max)
--2. Prepare for modify
IF EXISTS (
SELECT 1
FROM tempdb..sysobjects
WHERE NAME LIKE '%#filetable%'
)
BEGIN
DROP TABLE #filetable
END
CREATE TABLE #filetable (
mdf VARCHAR(255)
,ldf VARCHAR(255)
,dbid TINYINT
,dbname VARCHAR(100)
,fileid TINYINT
,logicalname SYSNAME
)
--
INSERT #filetable (
mdf
,dbid
,fileid
,logicalname
)
SELECT physical_name
,database_id
,data_space_id
,NAME
FROM sys.master_files
WHERE data_space_id = 1
INSERT #filetable (
ldf
,dbid
,fileid
,logicalname
)
SELECT physical_name
,database_id
,data_space_id
,NAME
FROM sys.master_files
WHERE data_space_id = 0
UPDATE u
SET u.dbname = s.NAME
FROM #filetable u
INNER JOIN master..sysdatabases s ON u.dbid = s.dbid
UPDATE #filetable
SET mdf = replace(mdf, 'C:', 'D:')
,ldf = replace(ldf, 'C:', 'D:')
FROM #filetable
SELECT @dbid = min(dbid)
FROM #filetable
WHERE dbid > 4
WHILE @dbid IS NOT NULL
BEGIN
SELECT @SQLText = 'alter database [' + dbname + '] MODIFY FILE (Name = ' + logicalname + ' , FileName = N''' + ldf + ''');'
FROM #filetable
WHERE dbid = convert(VARCHAR, @dbid)
AND fileid = 0 -- Log file
PRINT @SQLText
--Exec(@SQLText)
SELECT @SQLText2 = 'alter database [' + dbname + '] MODIFY FILE (Name = ' + logicalname + ' , FileName = N''' + mdf + ''');'
FROM #filetable
WHERE dbid = convert(VARCHAR, @dbid)
AND fileid = 1 -- data file
PRINT @SQLText2
--Exec(@SQLText)
SELECT @dbid = min(dbid)
FROM #filetable
WHERE dbid > 4
AND dbid > @dbid
END
--- ใช้วิธีการ Detach / Attach แบบเก่า (ไม่ต้องการ แต่ก็ยังมีคนใช้อยู่ .. น่าเสียดายที่ฉันใช้มันเมื่อไม่นานมานี้บนเซิร์ฟเวอร์ NON prod)
DECLARE @datafile VARCHAR(255)
,@logfile VARCHAR(255)
,@dbid TINYINT
,@SQLText VARCHAR(8000)
,@dbname VARCHAR(255)
,@SQLText2 VARCHAR(8000)
--2. Detach All Local Databases and prepare for Attach
IF EXISTS (
SELECT 1
FROM tempdb..sysobjects
WHERE NAME LIKE '%#filetable%'
)
BEGIN
DROP TABLE #filetable
END
CREATE TABLE #filetable (
mdf VARCHAR(255)
,ldf VARCHAR(255)
,dbid TINYINT
,dbname VARCHAR(100)
,fileid TINYINT
)
--
INSERT #filetable (
mdf
,dbid
,fileid
)
SELECT physical_name
,database_id
,data_space_id
FROM sys.master_files
WHERE data_space_id = 1
INSERT #filetable (
ldf
,dbid
,fileid
)
SELECT physical_name
,database_id
,data_space_id
FROM sys.master_files
WHERE data_space_id = 0
UPDATE u
SET u.dbname = s.NAME
FROM #filetable u
INNER JOIN master..sysdatabases s ON u.dbid = s.dbid
UPDATE #filetable
SET mdf = replace(mdf, 'C:', 'D:')
,ldf = replace(ldf, 'C:', 'D:')
FROM #filetable
SELECT @dbid = min(dbid)
FROM #filetable
WHERE dbid > 4
WHILE @dbid IS NOT NULL
BEGIN
SELECT @SQLText = 'alter database [' + dbname + ']'
FROM #filetable
WHERE dbid = convert(VARCHAR, @dbid)
SELECT @SQLText = @SQLText + CHAR(10) + ' set single_user with rollback immediate;'
SELECT @SQLText = @SQLText + CHAR(10) + ' exec master..sp_detach_db ' + dbname
FROM #filetable
WHERE dbid = convert(VARCHAR, @dbid)
PRINT @SQLText
--Exec(@SQLText)
SELECT @SQLText2 = 'exec master..sp_attach_db ''' + dbname + ''''
FROM #filetable
WHERE dbid = @dbid
SELECT @SQLText2 = @SQLText2 + ',''' + mdf + ''''
FROM #filetable
WHERE dbid = @dbid
AND mdf IS NOT NULL
SELECT @SQLText2 = @SQLText2 + ',''' + ldf + ''''
FROM #filetable
WHERE dbid = @dbid
AND ldf IS NOT NULL
PRINT @SQLText2
--Exec(@SQLText)
SELECT @dbid = min(dbid)
FROM #filetable
WHERE dbid > 4
AND dbid > @dbid
END
DROP TABLE #filetable