2012-03-09 124 views
61

是否可以列出有关SQL Server上所有数据库的文件(MDF/LDF)的信息?有关SQL Server中所有数据库文件的列表信息

我想获得一个列表,显示哪个数据库正在使用本地磁盘上的文件。

我试了一下:

  • exec sp_databases所有数据库
  • select * from sys.databases显示了很多有关每个数据库的信息 - 但遗憾的是它并不显示每个数据库使用的文件。
  • select * from sys.database_files显示master数据库的MDF/LDF文件 - 而不是其他数据库

回答

78

您可以使用sys.master_files

包含存储在主数据库 数据库中的每个数据库文件的行。这是一个单一的系统范围的观点。

+3

谢谢,(与sys.databases结合)是我一直在寻找! – M4N 2012-03-09 07:39:42

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 

大小(KB)表示。

51

如果你想得到数据库的位置,你可以检查Get All DBs Location
您可以使用sys.master_files为数据库获取位置和sys.databse获得DB名称

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 2015-02-10 01:14:53

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.databases表中的每一行查询sys.master_files表两次。 – Davos 2015-02-10 01:13:32

+2

除了达沃斯的评论......如果您有任何数据库的多个数据文件或日志文件,此脚本也会失败并出现错误。 (例如,子查询返回的值超过1)。 – Arkaine55 2015-03-05 23:12:36

+0

@Davos我知道你在说什么,但它取决于你执行这个查询的频率,否则它可能是你不需要的预优化。 – adeel41 2015-03-27 16:57:03

-2

您可以使用以下:

SP_HELPDB [Master] 
GO 
+0

这只提供单个指定数据库的信息。问题是所有数据库。 – Thronk 2015-09-24 15:27:46

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] 
相关问题