El caso práctico para el que he tenido que hacer el siguiente script: Una base de datos de 400GB con el 50% del espacio libre.
Intentar un shrink de 200GB podrÃa haber durado varias horas. En algunos foros habrás encontrado que es más efectivo reducir en tramos de 500MB o 1GB, y eso es lo que conseguiras con este script:
-- Shrink por etapas
DECLARE @mb_comienzo INT
DECLARE @mb_limite INT
SET @mb_comienzo = 440000 --Tamaño actual del fichero en MB
SET @mb_limite = 210000 -- Tamaño deseado en MB
USE [
WHILE (@mb_comienzo>@mb_limite)
BEGIN
SET @mb_comienzo = @mb_comienzo - 500
PRINT 'Reduciendo a: ' + CAST(@mb_comienzo AS VARCHAR) + 'MB.'
DBCC SHRINKFILE (N'
END
Se le puede añadir más complejidad. Pero es más que suficiente para salir del paso y empezar a obtener espacio libre en una situación de emergencia.
Por ejemplo, podrÃamos consultar qué datafiles son candidatos a ser reducidos con este procedimiento, porque tienen más de 10GB libres:
-- Ficheros candidatos a hacer el shrink por etapas (con más de 10GB para reducir)
DECLARE @sql VARCHAR(8000)
DECLARE @script VARCHAR(MAX)
SET @sql='SELECT DB_NAME() AS BD,
name AS FileName,
CONVERT(INT,size/128.0) AS MBactual,
CONVERT(INT,size/128.0 - CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT)/128.0) AS MBlibre
FROM sys.database_files
WHERE (size/128.0 - CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT)/128.0)>10000'
SET @script=''
SELECT @script = @script + 'USE ' + name + CHAR(13) + @sql + CHAR(13) + CHAR(13)
FROM sys.databases
--PRINT(@script)
EXECUTE(@script)