xp_fixeddrives не возвращает размеры дисков сервера, а иногда их все же требуется знать, причем включать поддержку скриптов/clr нельзя.
В итоге сегодня набросал процедуру приведенную ниже. Она вернет размеры всех дисков, на которых есть базы данных. Если на диске нет баз, но есть папка DATA или LOGS, то процедура создаст в них пустую базу данных, чтобы место все же определялось...
В общем, желающие могут пробовать.
В итоге сегодня набросал процедуру приведенную ниже. Она вернет размеры всех дисков, на которых есть базы данных. Если на диске нет баз, но есть папка DATA или LOGS, то процедура создаст в них пустую базу данных, чтобы место все же определялось...
В общем, желающие могут пробовать.
CREATE PROCEDURE GetDisks(@Drv char(1) = NULL) AS BEGIN SET NOCOUNT ON DECLARE @f tinyint = 0, @db sysname, @DefaultLogFolder sysname DECLARE @Sql nvarchar(MAX) DECLARE @Disks TABLE (Drv char(1), Total_MB int, Free_MB int, [Data] bit DEFAULT 0, Logs bit DEFAULT 0) DECLARE @Folders TABLE (Folder sysname) EXEC master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultLog', @DefaultLogFolder OUTPUT INSERT INTO @Disks (Drv, Free_MB) EXEC master..xp_fixeddrives IF NOT @Drv IS NULL DELETE FROM @Disks WHERE Drv <> @Drv UPDATE @Disks SET Total_MB = t.total_bytes / 1048576 FROM @Disks d INNER JOIN(SELECT DISTINCT UPPER(LEFT(volume_mount_point,1)) AS Drv, total_bytes FROM sys.master_files f CROSS APPLY sys.dm_os_volume_stats(f.database_id, f.file_id)) t ON d.Drv = t.Drv DECLARE cur CURSOR FOR SELECT Drv FROM @Disks OPEN cur FETCH NEXT FROM cur INTO @Drv WHILE @@FETCH_STATUS = 0 BEGIN SET @f = 0 DELETE FROM @Folders INSERT INTO @Folders EXEC('EXEC master..xp_subdirs ''' + @Drv + ':\''') IF EXISTS(SELECT * FROM @Folders WHERE Folder='DATA') BEGIN SET @f = 1 UPDATE @Disks SET [Data] = 1 WHERE Drv = @Drv END IF EXISTS(SELECT * FROM @Folders WHERE Folder='LOGS') BEGIN IF @f = 0 SET @f = 2 UPDATE @Disks SET [Logs] = 1 WHERE Drv = @Drv END IF @f > 0 AND EXISTS(SELECT * FROM @Disks WHERE Drv = @Drv AND Total_MB IS NULL) BEGIN SET @db = 'z_disk_' + @Drv EXEC ('DROP DATABASE IF EXISTS ' + @db) SET @Sql =' CREATE DATABASE ' + @db + ' ON ( NAME = ' + @db + '_dat, FILENAME = ''' + @Drv + ':\' + CASE WHEN @f = 1 THEN 'DATA' ELSE 'LOGS' END + '\' + @db + '_dat.mdf'' ) LOG ON ( NAME = ' + @db + '_log, FILENAME = ''' + @DefaultLogFolder + '\' + @db + '_log.ldf'' )' EXEC ( @Sql) UPDATE @Disks SET Total_MB = total_bytes / 1048576 FROM @Disks d INNER JOIN (SELECT UPPER(LEFT(volume_mount_point,1)) AS Drv, total_bytes FROM sys.database_files f CROSS APPLY sys.dm_os_volume_stats(DB_ID( @db ), f.file_id)) t ON d.Drv=t.Drv END FETCH NEXT FROM cur INTO @Drv END CLOSE cur DEALLOCATE cur DELETE FROM @Disks WHERE [Data]=0 AND Logs=0 AND Drv <> 'C' SET NOCOUNT OFF SELECT * FROM @Disks END