假设 SQL Server 2005 / 2008 具有大量数据库。有什么方法可以快速判断哪个数据库(如果有)附加到特定的 .mdf 文件?
随着时间的推移,我们已经删除了一些数据库,并希望清理一些挥之不去的 .mdf 文件以清理服务器上的空间。目前我知道的唯一方法是在 Management Studio 中逐个查看每个数据库的属性,并列出它们附加到的文件。寻找比这更有效的东西,如果有的话。
假设 SQL Server 2005 / 2008 具有大量数据库。有什么方法可以快速判断哪个数据库(如果有)附加到特定的 .mdf 文件?
随着时间的推移,我们已经删除了一些数据库,并希望清理一些挥之不去的 .mdf 文件以清理服务器上的空间。目前我知道的唯一方法是在 Management Studio 中逐个查看每个数据库的属性,并列出它们附加到的文件。寻找比这更有效的东西,如果有的话。
sys.master_files每个数据库包含该数据库的第一个文件 (id = 1) 的一行。也就是说,对于每个数据库,系统表将始终位于 fileid = 1
这就是你所需要的:
SELECT
DB_NAME(database_id), physical_name
FROM
sys.master_files
这可能会有所帮助。
declare @files table (
db_name sysname,
physical_name nvarchar(260)
)
insert into @files
exec sp_MSforeachdb 'select "?", physical_name from ?.sys.database_files'
select db_name, physical_name
from @files
您也可以为此使用OrcaMDF:
using (var file = new MdfFile(@"C:\Database.mdf"))
{
var bootPage = file.GetBootPage();
Console.WriteLine(bootPage.DatabaseName);
}
这将允许您在不将它们附加到数据库服务器的情况下查询 mdf 的数据库名称。请注意,这应该在主数据文件上完成,以防有多个文件。免责声明 - 我是 OrcaMDF 的作者。
循环遍历数据目录中的所有文件,很容易将其与 sys.databases 连接并查看哪些不匹配,因此是未附加的 mdf 文件。
编辑:在我的博客上发布了一个更详尽的示例:http: //improve.dk/archive/2011/05/19/checking-which-database-is-stored-in-a-deattached-mdf-file.aspx
select db_name(database_id), * from sys.master_files
将列出系统上所有已知数据库的所有文件。
低技术解决方案...将 mdf 文件移动到另一个位置。如果它是附加的,SQL 服务器不会让你移动它 :)
从命令提示符
cd X:\TheDir\Where\MDF\File\Are
mkdir UnusedMdf
move *.mdf UnusedDBFiles
move *.ldf UnusedDBFiles
所有未使用的文件都将移至 UnusedDBFiles。
private bool IsDbAttached()
{
const string isAttachedSqL = @"SELECT count(*)
FROM sys.master_files
WHERE DB_NAME(database_id) = @DbName";
bool isAttached = false;
try
{
using (var connection = new SqlConnection(this.connectionString))
using (var command = new SqlCommand(isAttachedSqL, connection))
{
command.Parameters.Add("@DbName", SqlDbType.VarChar).Value = "dbName";
connection.Open();
var count = command.ExecuteScalar();
isAttached = (int)count > 0;
}
}
catch
{
throw;
}
return isAttached;
}