我使用SQL Server 2005 Express用户实例进行单元测试。每个测试都会随机生成一个数据库名称,因此连接字符串如下所示:
Data Source=.\SQLEXPRESS2005;Database=MyTest_624332256;User Instance=true;Integrated Security=SSPI;
其中624332256
是随机生成的数字。
最后,我想删除所有这些数据库文件(.MDF
和.LDF
)。
如果我致电sp_detach_db
甚至DROP DATABASE
,它会从sys.databases
删除数据库实例,但数据库文件仍保留在%LOCALAPPDATA%\Microsoft\Microsoft SQL Server Data\SQLEXPRESS2005
我如何删除文件?我认为DROP DATABASE
应该这样做,但事实并非如此!
答案 0 :(得分:0)
我最终编写代码来手动执行此操作,查询物理文件名:
public static void CleanUpAllTestDbs()
{
using (var connection = new SqlConnection(connString))
{
connection.Open();
var dbNames = new List<string>();
using (var command = connection.CreateCommand())
{
command.CommandText = @"
USE master
SELECT name FROM sysdatabases WHERE name LIKE 'MyTest_%'";
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
dbNames.Add(reader.GetString(0));
}
}
}
foreach (var dbName in dbNames)
{
GetDatabaseFiles(connection, dbName, databaseFiles);
DetachDatabase(connection, dbName);
}
}
// Delete the physical files
foreach (var filePath in databaseFiles)
{
File.Delete(filePath);
}
}
private static void DetachDatabase(DbConnection connection, string dbName)
{
using (var command = connection.CreateCommand())
{
command.CommandText = string.Format(@"
USE master
ALTER DATABASE [{0}] SET OFFLINE WITH ROLLBACK IMMEDIATE
DROP DATABASE [{0}]", dbName);
try
{
command.ExecuteNonQuery();
}
catch (SqlException ex)
{
if (!ex.Message.StartsWith("Unable to open the physical file", StringComparison.OrdinalIgnoreCase))
throw;
}
}
}
private static void GetDatabaseFiles(DbConnection connection, string dbName, List<string> results)
{
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT physical_name FROM [" + dbName + "].sys.database_files";
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
results.Add(reader.GetString(0));
}
}
}
}