通过C#删除SQL Server数据库

16

我正在使用这段代码通过C#来删除一个数据库

Int32 result = 0;

try
{
        String Connectionstring = CCMMUtility.CreateConnectionString(false, txt_DbDataSource.Text, "master", "sa", "happytimes", 1000);

        SqlConnection con = new SqlConnection();
        con.ConnectionString = Connectionstring;

        String sqlCommandText = "DROP DATABASE [" + DbName + "]";
        if (con.State == ConnectionState.Closed)
        {
            con.Open();
            SqlConnection.ClearPool(con);
            con.ChangeDatabase("master");
            SqlCommand sqlCommand = new SqlCommand(sqlCommandText, con);
            sqlCommand.ExecuteNonQuery();
        }
        else
        {
            con.ChangeDatabase("master");
            SqlCommand sqlCommand = new SqlCommand(sqlCommandText, con);
            sqlCommand.ExecuteNonQuery();
        }



        con.Close();
        con.Dispose();
        result = 1;
    }
    catch (Exception ex)
    {
        result = 0;
    }
    return result;

但是我遇到了一个错误

数据库当前正在使用中

有人可以帮忙吗?


哪一行代码抛出了异常? - Soner Gönül
可能是 https://dev59.com/Rm435IYBdhLWcg3w3EEi 的重复问题。 - Rui Jarimba
sqlCommand.ExecuteNonQuery(); 抛出异常。 - Anshuman Jasrotia
@FrankvanPuffelen 你的解决方案有效。谢谢。 - Anshuman Jasrotia
请参考以下代码 从C#中删除数据库 以获取答案。 - mheyman
CCMMUtility是什么? - GWhite
8个回答

31

试试这个:

String sqlCommandText = @"
ALTER DATABASE " + DbName + @" SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE [" + DbName + "]";

还要确保你的连接字符串将默认数据库设置为master数据库,或者任何其他的数据库而不是你要删除的那个数据库!

另外,你真的不需要在查询周围添加所有那些东西。连接状态始终会开始于Closed,所以你不需要检查它。同样地,使用using语句块可以消除显式关闭或处理连接的需要。你真正需要做的只是:

String Connectionstring = CCMMUtility.CreateConnectionString(false, txt_DbDataSource.Text, "master", "sa", "happytimes", 1000);

using(SqlConnection con = new SqlConnection(Connectionstring)) {
    con.Open();
    String sqlCommandText = @"
        ALTER DATABASE " + DbName + @" SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
        DROP DATABASE [" + DbName + "]";
    SqlCommand sqlCommand = new SqlCommand(sqlCommandText, con);
    sqlCommand.ExecuteNonQuery();
}
result = 1;

我需要在修改语句的DbName周围加上方括号[],因为我的DbName中有一些破折号(GUID)。然后它就可以完美运行了。 - Christophe Lambrechts
SqlCommand继承自其父类IDisposable实现,应该在using块中进行保护。 - David Burg

26

以下是使用Entity Framework 6的操作步骤

System.Data.Entity.Database.Delete(connectionString);

你在开玩笑吧!我在网上找不到这个。惊讶于这个没有更高的投票。 - dwp4ge
这对我来说是最好的答案! - Boris Modylevsky
这需要实体 NuGet 引用吗? - Sandy
@Sandy 是的,你需要添加 EntityFramework 6 Nuget 包 dotnet add package EntityFramework 或者是 EntityFramework Core Nuget 包 dotnet add package Microsoft.EntityFrameworkCore.SqlServer - Bassem

4
你应该看一下SMO。这些工具允许你从代码中管理SQL Server的所有方面,包括删除数据库。
数据库对象具有Drop方法来删除数据库。

注意在项目中引用与生产环境不兼容的SMO dll文件。 - Micah Epps
@MicahEpps:为什么? - Tzwenni
请注意,在项目中引用与生产环境不兼容的SMO dlls,因为如果您在开发环境中安装了SS版本A,并部署到安装有版本B的客户端,则dlls将无法加载。 - Micah Epps

2
猜测您需要连接池技术的翻译,可以使用 SQL Server 的活动监视器进行确认。连接池会将数据库连接保持在缓存中,当您创建一个新的连接时,如果缓存中有可用的连接,它会将其返回,而不是实例化一个新的连接。这些连接会默认保留一段时间(我认为是2分钟),如果在此期间内没有被重复使用,则会被关闭。
因此,首先直接连接到主数据库,而不是使用“更改数据库”,因为我怀疑“更改数据库”只会在连接池中交换连接。添加一个正在使用的数据库检查程序(使用连接到主数据库)。您可以通过先执行命令来强制删除数据库。
ALTER DATABASE [MyDatabase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE

再次连接到主服务器!

然而,其他使用数据库的人将不再喜欢你...


2
创建一个 SQLConnection 对象,用于连接除了你想要删除的数据库之外的其他数据库。
sqlCommandText = "DROP DATABASE [DBNAME]";
sqlCommand = new SqlCommand(sqlCommandText , sqlconnection);
sqlCommand.ExecuteNonQuery();

1
这是我在问题中粘贴的内容。 - Anshuman Jasrotia
1
创建一个与要删除的数据库不同的sqlconnection对象。您不能使用同一数据库的连接来删除数据库。 - sreejithsdev
我已经使用 con.ChangeDatabase("master"); 更改了数据库。 - Anshuman Jasrotia

2

1

只需在连接字符串中不使用数据库名称。

"Data Source=.\SQLEXPRESS;Integrated Security=True;"

0
我遇到了和Anshuman一样的问题... 通过对Anshuman提出的代码进行测试,发现非常简单的错误: 应该使用SqlConnection.ClearAllPools();而不是SqlConnection.ClearPool(con);

像这种问题就会消失。

"无法删除数据库,因为它正在使用中..."


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接