Como você elimina todas as conexões atuais com um banco de dados SQL Server 2005?

StackOverflow https://stackoverflow.com/questions/11620

  •  08-06-2019
  •  | 
  •  

Pergunta

Quero renomear um banco de dados, mas continuo recebendo o erro 'não foi possível obter bloqueio exclusivo' no banco de dados, o que implica que há algumas conexões ainda ativas.

Como posso eliminar todas as conexões com o banco de dados para poder renomeá-lo?

Foi útil?

Solução

Ver Elimine todas as conexões ativas com um banco de dados.

A razão pela qual a abordagem que Adam sugeriu O que não funcionará é que, durante o tempo em que você estiver fazendo um loop nas conexões ativas, novas conexões poderão ser estabelecidas e você as perderá.O artigo ao qual vinculei usa a seguinte abordagem que não apresenta essa desvantagem:

-- 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

Outras dicas

Script para fazer isso, substitua 'DB_NAME' pelo banco de dados para eliminar todas as conexões com:

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

Mate-o e mate-o com fogo:

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

Usando o SQL Management Studio Express:

Na árvore do Object Explorer, faça uma busca detalhada em Gerenciamento até "Activity Monitor" (se você não conseguir encontrá-lo, clique com o botão direito no servidor de banco de dados e selecione "Activity Monitor").Abrindo o Activity Monitor, você pode visualizar todas as informações do processo.Você deve ser capaz de encontrar os bloqueios do banco de dados de seu interesse e eliminar esses bloqueios, o que também interromperá a conexão.

Você deve poder renomear depois disso.

Eu sempre usei:


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 
ALTER DATABASE [Test]
SET OFFLINE WITH ROLLBACK IMMEDIATE

ALTER DATABASE [Test]
SET ONLINE

Ficar off-line demora um pouco e às vezes tenho alguns problemas com isso.

Maneira mais sólida na minha opinião:

DesanexarClique com o botão direito em DB -> Tarefas -> Desanexar...Verifique "Drop Connections" OK

ReconectarClique com o botão direito em Bancos de Dados -> Anexar..Adicionar...-> selecione seu banco de dados e altere a coluna Anexar como para o nome do banco de dados desejado.OK

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

use o banco de dados 'mestre' e execute esta consulta, isso eliminará todas as conexões ativas do seu banco de dados.

Normalmente encontro esse erro quando tento restaurar um banco de dados. Normalmente, apenas vou até o topo da árvore no Management Studio, clico com o botão direito e reinicio o servidor de banco de dados (porque está em uma máquina de desenvolvimento, isso pode não ser ideal em produção ).Isso fecha todas as conexões de banco de dados.

No MS SQL Server Management Studio no explorador de objetos, clique com o botão direito no banco de dados.No menu de contexto a seguir, selecione 'Tarefas -> Ficar off-line'

Outra abordagem do tipo "matar com fogo" é simplesmente reiniciar o serviço MSSQLSERVER.Eu gosto de fazer coisas na linha de comando.Colar isso exatamente no CMD fará isso:NET STOP MSSQLSERVER e NET START MSSQLSERVER

Ou abra "services.msc" e encontre "SQL Server (MSSQLSERVER)" e clique com o botão direito e selecione "reiniciar".

Isso "com certeza, com certeza" eliminará TODAS as conexões com TODOS os bancos de dados em execução nessa instância.

(Gosto mais disso do que de muitas abordagens que alteram e alteram a configuração no servidor/banco de dados)

Veja como fazer esse tipo de coisa de maneira confiável no MS SQL Server Management Studio 2008 (pode funcionar para outras versões também):

  1. Na árvore do Object Explorer, clique com o botão direito no servidor de banco de dados raiz (com a seta verde) e clique em monitor de atividade.
  2. Abra a guia de processos no monitor de atividades, selecione o menu suspenso 'bancos de dados' e filtre pelo banco de dados desejado.
  3. Clique com o botão direito no banco de dados no Object Explorer e inicie uma tarefa 'Tasks -> Take Offline'.Deixe isso rodando em segundo plano enquanto você...
  4. Desligue com segurança tudo o que puder.
  5. Elimine todos os processos restantes na guia de processos.
  6. Coloque o banco de dados online novamente.
  7. Renomeie o banco de dados.
  8. Coloque seu serviço online novamente e aponte-o para o novo banco de dados.

A opção que funciona para mim neste cenário é a seguinte:

  1. Inicie a operação “Detach” no banco de dados em questão.Isso abrirá uma janela (no SQL 2005) exibindo as conexões ativas que impedem ações no banco de dados.
  2. Elimine as conexões ativas e cancele a operação de desconexão.
  3. O banco de dados agora deve estar disponível para restauração.

Experimente isto:

ALTER DATABASE [DATABASE_NAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE

Clique com o botão direito no nome do banco de dados, clique em Propriedade para obter a janela de propriedades, abra a guia Opções e altere a propriedade "Acesso restrito" de Multiusuário para Usuário único.Quando você clica no botão OK, ele solicitará que você feche todas as conexões abertas, selecione "Sim" e você estará pronto para renomear o banco de dados....

Isso não funcionou para mim (SQL2008 Enterprise), também não consegui ver nenhum processo em execução ou usuários conectados ao banco de dados.Reiniciar o servidor (clique com o botão direito em Sql Server no Management Studio e escolha Reiniciar) me permitiu restaurar o banco de dados.

Estou usando o SQL Server 2008 R2, meu banco de dados já estava configurado para usuário único e havia uma conexão que restringia qualquer ação no banco de dados.Assim o recomendado SQLMenace solução respondeu com erro. Aqui está um que funcionou no meu caso.

Eu uso sp_who para obter uma lista de todos os processos no banco de dados.Isso é melhor porque você pode querer revisar qual processo eliminar.

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

Resultado
Você pode usar o comando na coluna KillCommand para encerrar o processo desejado.

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

Você pode usar o comando SP_Who e eliminar todos os processos que usam seu banco de dados e renomear seu banco de dados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top