删除SQL Server Express用户实例数据库文件

时间:2012-08-08 05:30:29

标签: .net sql-server sql-server-express

我使用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应该这样做,但事实并非如此!

1 个答案:

答案 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));
            }
        }
    }
}