天天看點

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’的所有連接配接,則隻要在查詢分析器中執行[StopLogin ’DEMO’]即可, 如果您要斷開所有資料庫的連接配接進行維護的話則隻要執行[StopLogin ’’]即可.

下面用例子說明:

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'[dbo].[StopLogin]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)

    DROP PROCEDURE [dbo].[StopLogin]

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

       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  

           EXEC(@s)  

           FETCH NEXT FROM tb INTO @s  

       END  

       CLOSE tb  

       DEALLOCATE tb

END