SQL Server 2005 데이터베이스에 대한 현재 연결을 모두 어떻게 종료합니까?


288

데이터베이스의 이름을 바꾸고 싶지만 데이터베이스에서 '배타적 잠금을 얻을 수 없습니다'라는 오류가 계속 발생합니다. 이는 일부 연결이 아직 활성 상태임을 의미합니다.

데이터베이스에 대한 모든 연결을 종료하여 이름을 바꿀 수 있습니까?

답변:


378

Adam이 제안한 접근 방식이 작동하지 않는 이유 는 활성 연결을 반복하는 동안 새로운 연결을 설정할 수 있기 때문입니다. 대신이 단점이없는 다음 방법을 사용할 수 있습니다.

-- set your current connection to use master otherwise you might get an error

use master
ALTER DATABASE YourDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE 

--do you stuff here 

ALTER DATABASE YourDatabase SET MULTI_USER

1
SQL Server 2008에서는 작동하지 않는 것 같습니다. 여기에 내가받은 오류는 다음과 같습니다. 콘솔 : 메시지 102, 수준 15, 상태 1, 줄 4 '-'근처의 구문이 잘못되었습니다. 메시지 319, 수준 15, 상태 1, 줄 4 키워드 'with'근처의 구문이 잘못되었습니다. 이 명령문이 공통 테이블 표현식, xmlnamespaces 절 또는 변경 추적 컨텍스트 절인 경우, 이전 명령문은 세미콜론으로 끝나야합니다. 메시지 102, 수준 15, 상태 1, 줄 4 'IMMEDIATE'근처의 구문이 잘못되었습니다. 명령 : ALTER DATABASE ASMR-wdanda SET SINGLE_USER WITH ROLLBACK IMMEDIATE
Wagner da Silva

방금 2008 년 문제없이 ALTER DATABASE aspnetdb SET SINGLE_USER with ROLLBACK IMMEDIATE 선택 GETDATE () ALTER DATABASE aspnetdb SET MULTI_USER 주석 처리 된 코드 대신 무엇을해야합니까?
SQLMenace

SQL Server 2008 및 SQL Express 인스턴스와 함께 일했습니다.
Tim Murphy

19
@Wagner 데이터베이스가있는 경우는 '-'당신이 그것을 주위에 괄호를 사용하는 데 필요한 이름 : ALTER의 DATABASE [foo는 바] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
벤 Challenor

14
참고-Amazon RDS에서 호스팅되는 SQL Server에서는이 작업을 시도하지 마십시오. DB를 MULTI_USER 모드로 다시 재설정 할 수 없습니다. 시도하기 전에 다른 DBA 신임 정보 세트가 있는지 확인하십시오. 이전 스냅 샷 중 하나로 되돌려 서이 문제를 해결했습니다. 일부 데이터가 손실되었습니다. 운 좋게도 데이터는 중요하지 않았습니다.
RuntimeException

110

이를 수행하기위한 스크립트, 'DB_NAME'을 데이터베이스로 바꾸어 다음에 대한 모든 연결을 종료하십시오.

USE master
GO

SET NOCOUNT ON
DECLARE @DBName varchar(50)
DECLARE @spidstr varchar(8000)
DECLARE @ConnKilled smallint
SET @ConnKilled=0
SET @spidstr = ''

Set @DBName = 'DB_NAME'
IF db_id(@DBName) < 4
BEGIN
PRINT 'Connections to system databases cannot be killed'
RETURN
END
SELECT @spidstr=coalesce(@spidstr,',' )+'kill '+convert(varchar, spid)+ '; '
FROM master..sysprocesses WHERE dbid=db_id(@DBName)

IF LEN(@spidstr) > 0
BEGIN
EXEC(@spidstr)
SELECT @ConnKilled = COUNT(1)
FROM master..sysprocesses WHERE dbid=db_id(@DBName)
END

1
이것은 나를 위해 일했고, 현재 연결을 종료하려고 시도하지 않아서 오류 메시지가 생성되도록 명령문에 추가 and spid <> @@SPID했습니다 SELECT @sKillConnection.
Luis Perez

사용자 프로세스 만 종료 할 수 있습니다 ... 여전히 교착 상태이며 교착 상태로 인해 multi_user 모드를 복원 할 수 없습니다.
rainabba

mateuscb- mssql 10.00에서 작동하지 않는 유일한 방법은 []가 필요한 데이터베이스 이름이 있고 사용하지 않는 경우입니다. ALTER DATABASE [귀하의 데이터베이스] SET SINGLE_USER WITH ROLLBACK IMMEDIATE는 10, 10.5, 11 및 12에서 작동합니다.
Jeremy

생명의 은인. 최고 답변이어야합니다.
gls123

55

그것을 죽이고 불로 죽여라.

USE master
go

DECLARE @dbname sysname
SET @dbname = 'yourdbname'

DECLARE @spid int
SELECT @spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname)
WHILE @spid IS NOT NULL
BEGIN
EXECUTE ('KILL ' + @spid)
SELECT @spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname) AND spid > @spid
END

27

SQL Management Studio Express 사용 :

개체 탐색기 트리에서 관리에서 "활동 모니터"로 드릴 다운합니다 (찾을 수 없으면 데이터베이스 서버를 마우스 오른쪽 단추로 클릭하고 "활동 모니터"를 선택하십시오). 활동 모니터를 열면 모든 프로세스 정보를 볼 수 있습니다. 관심있는 데이터베이스에 대한 잠금을 찾고 해당 잠금을 종료하면 연결이 끊어집니다.

그 후에 이름을 바꿀 수 있어야합니다.


관리에이 "활동 모니터"항목이 표시되지 않습니다 ... 다시, SQL 2008을 사용하고 있기 때문일 수 있습니다.
바그너 다 실바

14
DB가 아닌 SERVER를 마우스 오른쪽 버튼으로 클릭하면 "Activity Montior"가 발견되었습니다. 그런 다음 '프로세스'탭을 선택하고 데이터베이스별로 필터링 할 수 있습니다.
alirobe

중단 된 프로세스를 하나씩 종료해야하지만 로컬 로그인이나 전체 데이터베이스 서버를 다운시킬 필요가없는 간단한 방법입니다.
Álvaro González

24

나는 항상 사용했다 :


ALTER DATABASE DB_NAME SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
GO 
SP_RENAMEDB 'DB_NAME','DB_NAME_NEW'
Go 
ALTER DATABASE DB_NAME_NEW  SET MULTI_USER -- set back to multi user 
GO 


14

오프라인 상태로 전환하는 데 시간이 걸리고 때로는 문제가 있습니다 ..

내 의견으로는 가장 확실한 방법 :

떼다 DB-> 작업-> 분리 ...를 마우스 오른쪽 단추로 클릭하십시오. "연결 끊기"를 확인하십시오. 확인

다시 연결 데이터베이스-> 첨부 ...를 마우스 오른쪽 단추로 클릭하십시오. 추가 ...-> 데이터베이스를 선택하고 다른 이름으로 첨부 열을 원하는 데이터베이스 이름으로 변경하십시오. 확인


좋아요 GUI에서 가장 빠른 방법입니다.
Whelkaholism

그것은 매력처럼 작동합니다! 쉬운 방법은 좋은 방법입니다. 감사.
Tug Strongly

6
Select 'Kill '+ CAST(p.spid AS VARCHAR)KillCommand into #temp
from master.dbo.sysprocesses p (nolock)
join master..sysdatabases d (nolock) on p.dbid = d.dbid
Where d.[name] = 'your db name'

Declare @query nvarchar(max)
--Select * from #temp
Select @query =STUFF((                              
            select '  ' + KillCommand from #temp
            FOR XML PATH('')),1,1,'') 
Execute sp_executesql @query 
Drop table #temp

'마스터'데이터베이스를 사용하고이 쿼리를 실행하면 데이터베이스에서 모든 활성 연결이 종료됩니다.


1
그것은 실제로 작동합니다 :) 나는이 스크립트의 실행 부분을 주석 처리하고 대신 print @query를 넣는 것이 좋습니다. 실제로 프로덕션 서버에서 이것을 실행하지 않도록하십시오.
Marcello Miorelli

5

데이터베이스를 복원하려고 할 때 일반적으로 오류가 발생합니다. 일반적으로 Management Studio의 트리 맨 위로 이동하여 데이터베이스 서버를 마우스 오른쪽 버튼으로 클릭하고 다시 시작하십시오 (개발 시스템에 있기 때문에 프로덕션 환경에 이상적이지 않을 수 있음) ). 이것은 모든 데이터베이스 연결을 닫습니다.


감사합니다, 이것은 작동했습니다 ( ALTER DATABASE ... SET SINGLE_USER다른 답변 의 명령은 동일한 '독점 잠금을 얻을 수 없습니다'오류를 반환했습니다).
Tinister

4

개체 탐색기의 MS SQL Server Management Studio에서 데이터베이스를 마우스 오른쪽 단추로 클릭하십시오. 상황에 맞는 메뉴에서 '작업-> 오프라인으로 전환'을 선택하십시오.


4
활성 연결이 있으면이 작업을 수행 할 수 없습니다.
alirobe

4

또 다른 "화재로 죽이기"접근 방식은 MSSQLSERVER 서비스를 다시 시작하는 것입니다. 나는 커맨드 라인에서 물건을 좋아합니다. 이것을 CMD에 정확하게 붙여 넣으면 다음과 같이됩니다. NET STOP MSSQLSERVER & NET START MSSQLSERVER

또는 "services.msc"를 열고 "SQL Server (MSSQLSERVER)"를 찾아 마우스 오른쪽 단추로 클릭 한 후 "다시 시작"을 선택하십시오.

이렇게하면 해당 인스턴스에서 실행중인 모든 데이터베이스에 대한 모든 연결이 "확실히"종료됩니다.

(서버 / 데이터베이스의 구성을 변경하고 다시 변경하는 많은 접근 방식보다 이것을 좋아합니다)


'권장하지 않음'이란 무엇입니까? 해당 서버에 대한 연결이 걱정되지 않는 경우 (예 : 디버그 또는 준비 환경 (예 : 임시 다운 타임이있는 프로덕션 서버))가 가장 쉬운 방법 일 수 있습니다. 프로덕션의 경우 서비스를 다시 시작할 수 있으면 구성을 사용하지 않을 수 있습니다. 당신은 무엇을 하시겠습니까?
aikeru

1
대상 DB에만 영향을 미치는 모든 것을 추구합니다. 대상 서버에서 모든 DB를 종료하는 방법은 그렇게 똑똑하지 않습니다. 그러나 솔직히 말하면 스테이징 환경에서 이것은 가장 쉬운 방법 일 것입니다.
Mohammed Swillam

4

MS SQL Server Management Studio 2008에서 이러한 종류의 작업을 안정적으로 수행하는 방법은 다음과 같습니다 (다른 버전에서도 작동 할 수 있음).

  1. 오브젝트 탐색기 트리에서 루트 데이터베이스 서버 (녹색 화살표)를 마우스 오른쪽 단추로 클릭 한 후 활동 모니터를 클릭하십시오.
  2. 활동 모니터에서 프로세스 탭을 열고 '데이터베이스'드롭 다운 메뉴를 선택한 후 원하는 데이터베이스를 기준으로 필터링하십시오.
  3. Object Explorer에서 DB를 마우스 오른쪽 버튼으로 클릭하고 'Tasks-> Take Offline'태스크를 시작하십시오. 당신이 동안 배경 에서이 실행을 남겨주세요 ...
  4. 가능한 모든 것을 안전하게 종료하십시오.
  5. 프로세스 탭에서 나머지 프로세스를 모두 종료하십시오.
  6. DB를 다시 온라인 상태로 만듭니다.
  7. DB 이름을 바꿉니다.
  8. 서비스를 다시 온라인 상태로 만들고 새 DB를 지정하십시오.

3

이 시나리오에서 나를 위해 일하는 옵션은 다음과 같습니다.

  1. 해당 데이터베이스에서 "분리"조작을 시작하십시오. 그러면 DB에 대한 작업을 방해하는 활성 연결을 표시하는 창이 열립니다 (SQL 2005).
  2. 활성 연결을 끊고 분리 작업을 취소하십시오.
  3. 이제 데이터베이스를 복원 할 수 있어야합니다.

SQL 2008 Management Studio에서는 어떤 이유로 든 "분리"화면에서 더 이상 활성 연결에 액세스 할 수 없습니다. 2005 년에 훌륭하게 작동하며 2008 년으로 업그레이드 할 때까지 항상 그렇게했습니다. 이제 모든 연결을 끊으라고 알려주는 연결 메시지를 표시하지만 각 연결을 끊기 위해 연결 세부 정보를 열 수는 없습니다. .
Jim


2

데이터베이스 이름을 마우스 오른쪽 버튼으로 클릭하고 속성을 클릭하여 속성 창을 가져온 후 옵션 탭을 열고 "액세스 제한"속성을 다중 사용자에서 단일 사용자로 변경하십시오. 확인 버튼을 누르면 열려있는 모든 연결을 닫고 "예"를 선택하면 데이터베이스 이름을 바꾸도록 설정됩니다 ....


2

이것들은 저에게 효과적이지 않았습니다 (SQL2008 Enterprise). 또한 실행중인 프로세스 나 DB에 연결된 사용자를 볼 수 없었습니다. 서버를 다시 시작하면 (Management Studio에서 Sql Server를 마우스 오른쪽 단추로 클릭하고 다시 시작 선택) DB를 복원 할 수있었습니다.



0

sp_who를 사용하여 데이터베이스의 모든 프로세스 목록을 가져옵니다. 어떤 프로세스를 종료할지 검토하고 싶을 수 있기 때문에이 방법이 더 좋습니다.

declare @proc table(
    SPID bigint,
    Status nvarchar(255),
    Login nvarchar(255),
    HostName nvarchar(255),
    BlkBy nvarchar(255),
    DBName nvarchar(255),
    Command nvarchar(MAX),
    CPUTime bigint,
    DiskIO bigint,
    LastBatch nvarchar(255),
    ProgramName nvarchar(255),
    SPID2 bigint,
    REQUESTID bigint
)

insert into @proc
exec sp_who2

select  *, KillCommand = concat('kill ', SPID, ';')
from    @proc

결과
KillCommand 열의 명령을 사용하여 원하는 프로세스를 종료 할 수 있습니다.

SPID    KillCommand
26      kill 26;
27      kill 27;
28      kill 28;

-1

SP_Who 명령을 사용하여 데이터베이스를 사용하는 모든 프로세스를 종료 한 다음 데이터베이스 이름을 바꿀 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.