Mover bases de datos de SQL Server a un nuevo volumen — ya sea para reequilibrar la E/S entre almacenamientos, migrar a discos más rápidos o recuperar espacio — requiere un enfoque metódico para evitar sorpresas de tiempo de inactividad. El método detach/attach es la opción más rápida cuando puede permitirse una breve ventana sin conexión: no implica copias de seguridad ni sobrecarga de transferencia por red. Este metascript genera las instrucciones completas de desconexión, movimiento de archivos y reconexión para cada base de datos que desee reubicar.
Cuándo Usar Detach/Attach frente a Backup/Restore
- Detach/Attach: el más rápido, no requiere espacio en disco adicional, pero exige que la base de datos esté sin conexión. Ideal para mover volúmenes locales en el mismo servidor.
- Backup/Restore: más flexible, funciona entre servidores y por red, el origen permanece en línea. Mejor para migraciones entre instancias.
- ALTER DATABASE … MODIFY FILE: operación en línea, sin tiempo de inactividad — pero solo funciona en SQL Server 2008+ y requiere un reinicio del servicio para que tenga efecto a nivel del sistema operativo. Ideal para planificación futura cuando no puede permitirse ningún tiempo de inactividad.
Qué Genera el Script
Para cada base de datos seleccionada, el script genera tres secciones: la instrucción de desconexión (con SINGLE_USER para terminar las conexiones activas), los comandos de movimiento de archivos a nivel del sistema operativo mediante xp_cmdshell, y la instrucción de reconexión con todas las rutas de archivos de datos actualizadas al nuevo destino. Use ALT+T en SSMS para mostrar los resultados como texto antes de ejecutar.
SET NOCOUNT ON
----------------------------------------------------
-- CONFIGURE HERE
----------------------------------------------------
-- Data files destination path
DECLARE @pathdata NVARCHAR(MAX) = 'D:DataPath'
-- Log files destination path
DECLARE @pathlog NVARCHAR(MAX) = 'L:LogPath'
----------------------------------------------------
-- DATABASE LIST
-- To move ALL user databases uncomment the INSERT below
----------------------------------------------------
CREATE TABLE #dbs (dbname NVARCHAR(255))
--INSERT INTO #dbs VALUES ('db1')
--INSERT INTO #dbs VALUES ('db2')
INSERT INTO #dbs
SELECT name FROM master..sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb')
----------------------------------------------------
DECLARE @aDB NVARCHAR(255)
DECLARE @script NVARCHAR(MAX) = ''
DECLARE db_cur CURSOR FOR SELECT dbname FROM #dbs
OPEN db_cur
FETCH NEXT FROM db_cur INTO @aDB
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT '============================================================'
PRINT ' DATABASE: ' + @aDB
PRINT '============================================================'
PRINT ''
PRINT '-- 1) SET SINGLE USER AND DETACH'
PRINT 'USE [master]'
PRINT 'ALTER DATABASE [' + @aDB + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE'
PRINT 'EXEC master.dbo.sp_detach_db @dbname = N''' + @aDB + ''', @keepfulltextindexfile = N''false'''
PRINT ''
PRINT '-- 2) MOVE FILES (adjust paths as needed)'
SELECT
PRINT 'exec xp_cmdshell ''move "' + physical_name + '" ' +
CASE WHEN type_desc = 'LOG' THEN @pathlog ELSE @pathdata END + ''''
FROM sys.master_files
WHERE DB_NAME(database_id) = @aDB
PRINT ''
PRINT '-- 3) ATTACH DATABASE WITH NEW PATHS'
-- (Re-attach script generation requires dynamic SQL per database)
FETCH NEXT FROM db_cur INTO @aDB
END
CLOSE db_cur
DEALLOCATE db_cur
DROP TABLE #dbs
Notas importantes: xp_cmdshell debe estar habilitado en la instancia para ejecutar los comandos de movimiento de archivos. Verifique que las rutas de destino existan y que la cuenta de servicio de SQL Server tenga permisos de escritura antes de ejecutar. Tras reconectar la base de datos, verifique la integridad con DBCC CHECKDB.








