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

Posted

技术标签:

【中文标题】无法删除数据库,因为它当前正在使用中【英文标题】:Cannot drop database because it is currently in use 【发布时间】:2011-11-20 02:42:51 【问题描述】:

我想删除一个数据库。我使用了以下代码,但没有用。

public void DropDataBase(string DBName,SqlConnection scon)

    try
    
        SqlConnection.ClearAllPools();
        SqlCommand cmd = new SqlCommand("ALTER DATABASE " + DBName + "     SET SINGLE_USER     WITH ROLLBACK IMMEDIATE", scon);
        cmd.CommandType = CommandType.Text;
        scon.Open();
        cmd.ExecuteNonQuery();
        scon.Close();

        SqlCommand cmddrpdb = new SqlCommand("drop database " + DBName + "", scon);
        cmddrpdb.CommandType = CommandType.Text;
        scon.Open();
        cmddrpdb.ExecuteNonQuery();
        scon.Close();
    
    catch (Exception ex)
    
        MessageBox.Show("DropDataBase : " +ex.Message);
    

我收到错误,因为 。 请帮助我解决上述问题。

【问题讨论】:

【参考方案1】:

在删除数据库之前,您需要先删除与目标数据库的所有连接。

我在http://www.kodyaz.com/articles/kill-all-processes-of-a-database.aspx找到了解决方案

DECLARE @DatabaseName nvarchar(50)
SET @DatabaseName = N'YOUR_DABASE_NAME'

DECLARE @SQL varchar(max)

SELECT @SQL = COALESCE(@SQL,'') + 'Kill ' + Convert(varchar, SPId) + ';'
FROM MASTER..SysProcesses
WHERE DBId = DB_ID(@DatabaseName) AND SPId <> @@SPId

--SELECT @SQL 
EXEC(@SQL)

【讨论】:

+1 我想知道你为什么没有早点得到这个,这是一个非常方便的答案。谢谢 那不会也引入非用户进程吗? 对我来说,我收到错误“KILL 命令不能在用户事务中使用。” 如果事务导致问题,请不要使用事务。 仅供参考,这似乎与您所说的一样,但并没有为我解决问题。【参考方案2】:

为时已晚,但它可能对未来的用户有用。

您可以在删除数据库查询之前使用以下查询:

 use master go
 alter database [MyDatbase] set single_user with rollback immediate

 drop database [MyDatabase]

它会起作用的。也可以参考

How do I specify "close existing connections" in sql script

希望对你有帮助:)

【讨论】:

如果您当前选择 [MyDatabase],也不要忘记在开头添加 use master go @ThànhChungBùi 你指出的解决了我的问题。它应该包含在答案中。谢谢。【参考方案3】:

有人连接到数据库。尝试切换到另一个数据库,然后将其删除:

试试

SP_WHO 看看谁连接了

如果需要,还有KILL

【讨论】:

对于 SQL 服务器管理。工作室:右键单击数据库:属性 -> 选项 -> 限制访问:设置为“单用户”,然后执行删除。 invoke-sqlcmd -ServerInstance localhost 'exec sp_who' | where-object $_.dbname -eq 'myDbName' 什么也不返回。然而它直到抱怨。这似乎并不实际工作。 @AceAlfred Yours 是最简单的。应该是答案之一。谢谢。【参考方案4】:

对于 SQL 服务器管理。工作室:

右键单击数据库:属性 -> 选项 -> 限制访问:设置为“单用户”,然后执行删除

【讨论】:

如果您想直接从 Management Studio 中删除数据库,这是最直观的解决方案。谢谢。 我做到了,然后使用了drop database myDatabase。它没有解决问题。发生了同样的错误 (... it is currently is use)。 @ShahryarSaljoughi 我只是按照 acealfred 的指示进行的。也许菜单方法除了简单的拖放之外还执行一些其他命令。【参考方案5】:

在 SQL Server Management Studio 2016 中,执行以下操作:

右键数据库

点击删除

检查关闭现有连接

执行删除操作

【讨论】:

【参考方案6】:
select * from sys.sysprocesses where dbid = DB_ID('Test')

(将“Test”替换为您要删除的数据库的名称) 这将告诉您哪些进程正在使用它。

如果还想强制drop的话,终极办法是:

USE master;
GO
ALTER DATABASE Test 
SET SINGLE_USER 
WITH ROLLBACK IMMEDIATE;
GO
DROP DATABASE Test;

希望这会有所帮助!

【讨论】:

【参考方案7】:

如果您在 SQL Management Studio 中删除数据库并收到消息,请不要忘记使用 Master 作为选定数据库,否则您的查询也是与数据库的连接。

USE Master;
GO
DROP DATABASE AdventureWorks;
GO

【讨论】:

我的情况是,我与我想删除的数据库有超过 1 个连接。【参考方案8】:

首先使您的数据库脱机,然后将其分离,例如

Use Master
GO
ALTER DATABASE dbname SET OFFLINE
GO
EXEC sp_detach_db 'dbname', 'true'

【讨论】:

我认为操作不会删除数据库。 分离数据库后,现在可以使用此查询将其删除。 DROP DATABASE dbname; 【参考方案9】:

首先检查连接的数据库

SP_WHO

第二次断开你的数据库

DECLARE @DatabaseName nvarchar(50)
SET @DatabaseName = N'your_database_name'

DECLARE @SQL varchar(max)

SELECT @SQL = COALESCE(@SQL,'') + 'Kill ' + Convert(varchar, SPId) + ';'
FROM MASTER..SysProcesses
WHERE DBId = DB_ID(@DatabaseName) AND SPId <> @@SPId

--SELECT @SQL 
EXEC(@SQL)

最终放弃

drop database your_database

【讨论】:

【参考方案10】:

蛮力解决方法可能是:

    停止 SQL Server 服务。

    删除对应的.mdf和.ldf文件。

    启动 SQL Server 服务。

    连接 SSMS 并删除数据库。

【讨论】:

它对我有用。谢谢。我认为问题是外部硬盘驱动器。我将文件切换到本地磁盘。感谢您的解决方案。【参考方案11】:

我想指出我使用的脚本源自以下两个答案。

@Hitesh Mistry 和 @unruledboy 的道具

DECLARE @DatabaseName nvarchar(50)
SET @DatabaseName = N'[[[DatabaseName]]]'

DECLARE @SQL varchar(max)

SELECT @SQL = COALESCE(@SQL,'') + 'Kill ' + Convert(varchar, SPId) + ';'
FROM MASTER..SysProcesses
WHERE DBId = DB_ID(@DatabaseName) AND SPId <> @@SPId

EXEC(@SQL)

alter database [[[DatabaseName]]] set single_user with rollback immediate

DROP DATABASE [[[DatabaseName]]]

【讨论】:

【参考方案12】:

使用 MS SQL Server 2008,在带有关闭连接选项的 DELETE 对话框中,这是生成的脚本,我想这是最好的:

EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N'YOUR_DATABASE_NAME'
GO
USE [master]
GO
ALTER DATABASE [YOUR_DATABASE_NAME] SET  SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
USE [master]
GO
/****** Object:  Database [YOUR_DATABASE_NAME]    Script Date: 01/08/2014 21:36:29 ******/
DROP DATABASE [YOUR_DATABASE_NAME]
GO

【讨论】:

这是 SQL Server Management Studio 编写的脚本,并且对我有用。我做的唯一不同的事情就是将所有这些都包裹在 USE [master] IF EXISTS(SELECT * FROM sys.databases WHERE name = 'Database_Name') BEGIN -- your script here END【参考方案13】:

只是想给一个 vb.net(如果想转换的话,就像 c 语言一样。)我在卸载我的一个程序时遇到了类似的问题,删除数据库有点棘手,是的可以让用户进入服务器使用 Express 删除它,但这并不干净,经过几次环顾后,我们得到了一些完美的代码......

    Sub DropMyDatabase()
    Dim Your_DB_To_Drop_Name As String = "YourDB"
    Dim Your_Connection_String_Here As String = "SERVER=MyServer;Integrated Security=True"
    Dim Conn As SqlConnection = New SqlConnection(Your_Connection_String_Here)

    Dim AlterStr As String = "ALTER DATABASE " & Your_DB_To_Drop_Name & " SET OFFLINE WITH ROLLBACK IMMEDIATE"
    Dim AlterCmd = New SqlCommand(AlterStr, Conn)

    Dim DropStr As String = "DROP DATABASE " & Your_DB_To_Drop_Name
    Dim DropCmd = New SqlCommand(DropStr, Conn)

    Try
        Conn.Open()
        AlterCmd.ExecuteNonQuery()
        DropCmd.ExecuteNonQuery()
        Conn.Close()

    Catch ex As Exception
        If (Conn.State = ConnectionState.Open) Then
            Conn.Close()
        End If
        MsgBox("Failed... Sorry!" & vbCrLf & vbCrLf & ex.Message)
    End Try
End Sub

希望这可以帮助任何寻找 x鸡x

更新 这里使用this转换器是C#版本:

public void DropMyDatabase()
    
        var Your_DB_To_Drop_Name = "YourDB";
        var Your_Connection_String_Here = "SERVER=MyServer;Integrated Security=True";
        var Conn = new SqlConnection(Your_Connection_String_Here);

        var AlterStr = "ALTER DATABASE " + Your_DB_To_Drop_Name + " SET OFFLINE WITH ROLLBACK IMMEDIATE";
        var AlterCmd = new SqlCommand(AlterStr, Conn);

        var DropStr = "DROP DATABASE " + Your_DB_To_Drop_Name;
        var DropCmd = new SqlCommand(DropStr, Conn);

        try
        
            Conn.Open();
            AlterCmd.ExecuteNonQuery();
            DropCmd.ExecuteNonQuery();
            Conn.Close();

        
        catch(Exception ex)
        
            if((Conn.State == ConnectionState.Open))
            
                Conn.Close();
            
            Trace.WriteLine("Failed... Sorry!" + Environment.NewLine + ex.Message);
        
    

【讨论】:

问题需要 C# 响应,因为它是这样标记的。 @MathiasLykkegaardLorenzen 有几个免费软件应用程序可以翻译所有语言的 .NET 代码。甚至还有在线应用程序。 点了。我会改变我的投票,但我不能,因为它被锁定了。 坏主意! 在数据库处于关闭状态时删除它不会删除数据库文件!即使这在某些特殊情况下可能很方便,但它不是您应该盲目遵循的模式。问题:a) 您的磁盘已满;b) 您在尝试使用相同的物理文件重新创建数据库时可能会遇到问题。【参考方案14】:

要删除正在运行的数据库,您可以使用此批处理文件

@echo off

set /p dbName= "Enter your database name to drop: " 

echo Setting to single-user mode
sqlcmd -Q "ALTER DATABASE [%dbName%] SET  SINGLE_USER WITH ROLLBACK IMMEDIATE"

echo Dropping...
sqlcmd -Q "drop database %dbName%"

echo Completed.

pause

【讨论】:

单用户模式的想法似乎是最干净的方法。【参考方案15】:

您不能删除当前正在使用的数据库,但是如果您想从服务器中删除数据库而不删除数据库文件,您可以使用sp_detach_db 存储过程。

【讨论】:

【参考方案16】:

只是重命名数据库(要删除)对我有用。它脱离了正在访问数据库的任何进程,因此我能够删除数据库。

【讨论】:

【参考方案17】:

转到可用数据库部分并选择主数据库。然后尝试 DROP DATABASE the_DB_name。

【讨论】:

【参考方案18】:

使用这个:

/* Delete Database Backup and Restore History from MSDB System Database */
EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N'[dba]'
GO

/* Query to Get Exclusive Access of SQL Server Database before Dropping the Database  */
USE [master]
GO

ALTER DATABASE [dba]

SET SINGLE_USER
WITH

ROLLBACK IMMEDIATE
GO

/* Query to Drop Database in SQL Server  */
DROP DATABASE [dba]
GO

【讨论】:

以上是关于无法删除数据库,因为它当前正在使用中的主要内容,如果未能解决你的问题,请参考以下文章

"无法删除数据库,因为该数据库当前正在使用"问题解决

SqlServer关于“无法删除数据库 "XXXX",因为该数据库当前正在使用”问题的解决方案

"无法删除数据库,因为该数据库当前正在使用"问题解决

无法删除数据库,因为它正在使用中 + EF 代码优先

为啥我收到错误“无法删除数据库'test',因为它正在用于复制。错误:3724”?

删除 SQL Server 数据库