狐狸情 发表于 2015-7-3 02:40:34

SQL Server中强制关闭数据库连接

  1.问题引入

        在SQL Server中备份/还原/分离/脱机/删除指定数据库时, 如果有其他用户正在使用此数据库时, SQL Server为了防止数据异常, 会报错而终止你的操作.
   当然, 在SQL 2005里, 在做[分离/删除]数据库时提供了一个选项[关闭所以连接]供勾选(SQL 2000好像没有哦), 然而[备份/还原]操作却没有此选择, 也许你会说可以先[脱机数据库]再做[备份还原]操作, 对, 但你会发现[脱机]处理太慢了J, 那在SQL2005以及SQL 2000下有哪些方法可以解决此问题呢???   
2.解决方法:
1. 拔掉此机器的网线. 呵呵, 这种方法立竿见影, 但是可能对其他的连接造成影响.
2. 通知连接至此数据库的用户断开连接. 如果可能连接的用户很多或不知道哪个用户正在连接的话就不可行了.
3. 在SQL Server中用命令StopLogin强行断开连接.详细说明如下:
使用说明:
StopLogin @Dname
其中@Dname为要强行断开连接的数据库名称, 如果您想断开数据库’DEMO’的所有连接,则只要在查询分析器中执行即可, 如果您要断开所有数据库的连接进行维护的话则只要执行即可.

下面用例子说明:
EX1. 使用StopLogin强行断开连接前后SQL的执行结果对比
首先, 我们执行如下SQL语句:

USE DEMO2
GO
SELECT TOP 1 * FROM INVMB
执行结果为:
查询已成功执行


下面我们来执行如下SQL语句:

StopLogin 'DEMO2'

执行结果为:
由于数据库'DEMO2' 离线,无法打开该数据库。

3. StopLogin详细代码(写的仓促, 若有bug请谅解)
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'.') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    DROP PROCEDURE .
GO

CREATE PROCEDURE StopLogin
    @Dname varchar(50)
AS
DECLARE
    @name varchar(50),
    @s varchar(1000)
BEGIN
    IF (@Dname = '')
    BEGIN
       DECLARE DataName CURSOR FOR
       SELECT name FROM sysdatabases WHERE name not in ('master')

       OPEN DataName

       FETCH NEXT FROM DataName
       INTO @name

       WHILE (@@FETCH_STATUS = 0)
       BEGIN   
         DECLARE tb CURSOR local   
         FOR   
         SELECT N'kill   '+CAST(spid AS varchar)   
         FROM master..sysprocesses   
         WHERE dbid=db_id(@name)   

         OPEN tb   

         FETCH next FROM tb INTO @s   

         WHILE @@FETCH_STATUS=0   
         BEGIN   
               EXEC(@s)   

               FETCH NEXT FROM tb INTO @s   
         END   

         CLOSE tb   
         DEALLOCATE tb
                        
         FETCH NEXT FROM DataName
         INTO @name
       END

       CLOSE DataName
       DEALLOCATE DataName
    END
    ELSE
    BEGIN
       DECLARE tb CURSOR local   
       FOR   
       SELECT N'kill   '+CAST(spid AS varchar)   
       FROM master..sysprocesses   
       WHERE dbid=db_id(@Dname)   

       OPEN tb   

       FETCH next FROM tb INTO @s

       WHILE @@FETCH_STATUS=0   
       BEGIN   
         EXEC(@s)   

         FETCH NEXT FROM tb INTO @s   
       END   

       CLOSE tb   
       DEALLOCATE tb
    END
  END


========================================================================
最好的方法就是 停止服务 即可,,,
页: [1]
查看完整版本: SQL Server中强制关闭数据库连接