2012-03-09 2 views
61

Возможно ли перечислить информацию о файлах (MDF/LDF) всех баз данных на SQL Server?Список информации обо всех файлах базы данных в SQL Server

Я хотел бы получить список, показывающий, какая база данных использует файлы на локальном диске.

Что я пробовал:

  • exec sp_databases все базы данных
  • select * from sys.databases показывает много информации о каждой базе данных - но, к сожалению, она не показывает файлы, используемые для каждой базы данных.
  • select * from sys.database_files показывает кросса/LDF файлы базы данных master - но не других баз данных

ответ

78

Вы можете использовать sys.master_files.

Содержит строку в файле базы данных, хранящуюся в базе данных . Это единое общесистемное представление.

+3

Спасибо, что (присоединился к sys.databases) - это то, что я искал! – M4N

13

Я использую скрипт, чтобы получить пустое пространство в каждом файле:

Create Table ##temp 
(
    DatabaseName sysname, 
    Name sysname, 
    physical_name nvarchar(500), 
    size decimal (18,2), 
    FreeSpace decimal (18,2) 
) 
Exec sp_msforeachdb ' 
Use [?]; 
Insert Into ##temp (DatabaseName, Name, physical_name, Size, FreeSpace) 
    Select DB_NAME() AS [DatabaseName], Name, physical_name, 
    Cast(Cast(Round(cast(size as decimal) * 8.0/1024.0,2) as decimal(18,2)) as nvarchar) Size, 
    Cast(Cast(Round(cast(size as decimal) * 8.0/1024.0,2) as decimal(18,2)) - 
     Cast(FILEPROPERTY(name, ''SpaceUsed'') * 8.0/1024.0 as decimal(18,2)) as nvarchar) As FreeSpace 
    From sys.database_files 
' 
Select * From ##temp 
drop table ##temp 

Размер выражается в КБ.

51

Если вы хотите получить местоположение Базы данных, вы можете проверить Get All DBs Location.
вы можете использовать sys.master_files для ПОЛУЧИТЬ расположения БД и sys.databse получить дб имя

SELECT 
    db.name AS DBName, 
    type_desc AS FileType, 
    Physical_Name AS Location 
FROM 
    sys.master_files mf 
INNER JOIN 
    sys.databases db ON db.database_id = mf.database_id 
+0

Спасибо, что я искал. – Davos

3

Выполнение следующего SQL (Это будет работать только тогда, когда у вас нет нескольких файлов MDF/LDF для одной базы данных)

SELECT 
    db.name AS DBName, 
    (select mf.Physical_Name FROM sys.master_files mf where mf.type_desc = 'ROWS' and db.database_id = mf.database_id) as DataFile, 
    (select mf.Physical_Name FROM sys.master_files mf where mf.type_desc = 'LOG' and db.database_id = mf.database_id) as LogFile 
FROM sys.databases db 

возвратит этот выход

DBName  DataFile      LogFile 
-------------------------------------------------------------------------------- 
master  C:\....\master.mdf   C:\....\mastlog.ldf 
tempdb  C:\....\tempdb.mdf   C:\....\templog.ldf 
model  C:\....\model.mdf   C:\....\modellog.ldf 

и остальных баз данных

Если у вашего TempDB есть несколько MDF (например, у меня есть), этот скрипт завершится с ошибкой. Однако, вы можете использовать

WHERE db.database_id > 4 

в конце, и он будет возвращать все базы данных, за исключением системных баз данных.

+0

Я понимаю, что это небольшой набор данных, но это не причина для использования коррелированных подзапросов. Они могут быть хороши в Oracle, но они являются серьезными убийцами производительности на SQL Server, потому что они вызывают по очереди обработку строк. Ваш скрипт будет запрашивать таблицу sys.master_files дважды для каждой строки в таблице sys.databases. – Davos

+2

В дополнение к комментарию Давоса ... Этот скрипт также потерпит неудачу с ошибками, если у вас есть несколько файлов данных или лог-файлов для любой базы данных. (например, подзапрос возвращает более 1 значения.) – Arkaine55

+0

@Davos Я знаю, что вы говорите, но зависит от того, как часто вы выполняете этот запрос, иначе это предварительная оптимизация, которая, вероятно, вам не нужна. – adeel41

-2

Вы можете использовать ниже:

SP_HELPDB [Master] 
GO 
+0

Это только информация для одной указанной базы данных. Вопрос для ВСЕХ баз данных. – Thronk

2

Вы также можете попробовать это.

select db_name(dbid) dbname, filename from sys.sysaltfiles 
0

Этот сценарий отображает большинство из того, что вы ищете, и, надеюсь, он будет изменен для вас. Обратите внимание, что там создается постоянная таблица - вы можете ее изменить. Это подмножество из более крупного сценария, который также суммирует информацию о резервном копировании и задании на разных серверах.

IF OBJECT_ID('tempdb..#DriveInfo') IS NOT NULL 
DROP TABLE #DriveInfo 
CREATE TABLE #DriveInfo 
(
    Drive CHAR(1) 
    ,MBFree INT 
) 

INSERT INTO #DriveInfo 
     EXEC master..xp_fixeddrives 


IF OBJECT_ID('[dbo].[Tmp_tblDatabaseInfo]', 'U') IS NOT NULL 
    DROP TABLE [dbo].[Tmp_tblDatabaseInfo] 
CREATE TABLE [dbo].[Tmp_tblDatabaseInfo](
     [ServerName] [nvarchar](128) NULL 
     ,[DBName] [nvarchar](128) NULL 
     ,[database_id] [int] NULL 
     ,[create_date] datetime NULL 
     ,[CompatibilityLevel] [int] NULL 
     ,[collation_name] [nvarchar](128) NULL 
     ,[state_desc] [nvarchar](60) NULL 
     ,[recovery_model_desc] [nvarchar](60) NULL 
     ,[DataFileLocations] [nvarchar](4000) 
     ,[DataFilesMB] money null 
     ,DataVolumeFreeSpaceMB INT NULL 
     ,[LogFileLocations] [nvarchar](4000) 
     ,[LogFilesMB] money null 
     ,LogVolumeFreeSpaceMB INT NULL 

) ON [PRIMARY] 

INSERT INTO [dbo].[Tmp_tblDatabaseInfo] 
SELECT 
     @@SERVERNAME AS [ServerName] 
     ,d.name AS DBName 
     ,d.database_id 
     ,d.create_date 
     ,d.compatibility_level 
     ,CAST(d.collation_name AS [nvarchar](128)) AS collation_name 
     ,d.[state_desc] 
     ,d.recovery_model_desc 
     ,(select physical_name + ' | ' AS [text()] 
     from sys.master_files m 
     WHERE m.type = 0 and m.database_id = d.database_id 
     ORDER BY file_id 
     FOR XML PATH ('')) AS DataFileLocations 
     ,(select sum(size) from sys.master_files m WHERE m.type = 0 and m.database_id = d.database_id) AS DataFilesMB 
     ,NULL 
     ,(select physical_name + ' | ' AS [text()] 
     from sys.master_files m 
     WHERE m.type = 1 and m.database_id = d.database_id 
     ORDER BY file_id 
     FOR XML PATH ('')) AS LogFileLocations 
     ,(select sum(size) from sys.master_files m WHERE m.type = 1 and m.database_id = d.database_id) AS LogFilesMB 
     ,NULL 
FROM sys.databases d 

WHERE d.database_id > 4 --Exclude basic system databases 
UPDATE [dbo].[Tmp_tblDatabaseInfo] 
    SET DataFileLocations = 
     CASE WHEN LEN(DataFileLocations) > 4 THEN LEFT(DataFileLocations,LEN(DataFileLocations)-2) ELSE NULL END 
    ,LogFileLocations = 
     CASE WHEN LEN(LogFileLocations) > 4 THEN LEFT(LogFileLocations,LEN(LogFileLocations)-2) ELSE NULL END 
    ,DataFilesMB = 
     CASE WHEN DataFilesMB > 0 THEN DataFilesMB * 8/1024.0 ELSE NULL END 
    ,LogFilesMB = 
     CASE WHEN LogFilesMB > 0 THEN LogFilesMB * 8/1024.0 ELSE NULL END 
    ,DataVolumeFreeSpaceMB = 
     (SELECT MBFree FROM #DriveInfo WHERE Drive = LEFT(DataFileLocations,1)) 
    ,LogVolumeFreeSpaceMB = 
     (SELECT MBFree FROM #DriveInfo WHERE Drive = LEFT(LogFileLocations,1)) 

select * from [dbo].[Tmp_tblDatabaseInfo] 
Смежные вопросы