Domanda

Voglio rinominare un database, ma continuo a ricevere l'errore "impossibile ottenere il blocco esclusivo" sul database, il che implica che ci sono alcune connessioni ancora attive.

Come posso interrompere tutte le connessioni al database in modo da poterlo rinominare?

È stato utile?

Soluzione

Vedere Uccidi tutte le connessioni attive a un database.

Il motivo per cui l'approccio è quello suggerì Adamo non funzionerà è che durante il tempo in cui esegui il loop sulle connessioni attive è possibile stabilirne una nuova e le perderai.L'articolo a cui ho collegato utilizza il seguente approccio che non presenta questo inconveniente:

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

Altri suggerimenti

Script per ottenere ciò, sostituisci 'DB_NAME' con il database per interrompere tutte le connessioni a:

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

Uccidilo e uccidilo con il fuoco:

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

Utilizzo di SQL Management Studio Express:

Nell'albero Esplora oggetti, esegui il drill-down in Gestione fino a "Monitoraggio attività" (se non riesci a trovarlo lì, fai clic con il pulsante destro del mouse sul server del database e seleziona "Monitoraggio attività").Aprendo Activity Monitor, puoi visualizzare tutte le informazioni sul processo.Dovresti essere in grado di trovare i blocchi per il database che ti interessa e di eliminarli, interrompendo anche la connessione.

Dovresti essere in grado di rinominarlo dopo.

Ho sempre utilizzato:


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

Disconnettersi richiede un po' di tempo e talvolta riscontro alcuni problemi con questo..

Il modo più solido secondo me:

StaccaFare clic con il pulsante destro del mouse su DB -> Attività -> Scollega...Controlla "Drop Connections" OK

RiattaccareFare clic con il pulsante destro del mouse su Database -> Allega..Aggiungere...-> seleziona il tuo database e modifica la colonna Allega come con il nome del database desiderato.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

utilizza il database "master" ed esegui questa query, ucciderà tutte le connessioni attive dal tuo database.

Di solito mi imbatto in questo errore quando provo a ripristinare un database. Di solito vado in cima all'albero in Management Studio e faccio clic con il tasto destro e riavvio il server del database (poiché è su una macchina di sviluppo, questo potrebbe non essere l'ideale in produzione ).Questo chiude tutte le connessioni al database.

In MS SQL Server Management Studio in Esplora oggetti, fare clic con il pulsante destro del mouse sul database.Nel menu contestuale che segue seleziona 'Attività -> Metti offline'

Un altro approccio "uccidilo con il fuoco" consiste nel riavviare semplicemente il servizio MSSQLSERVER.Mi piace fare cose dalla riga di comando.Incollarlo esattamente in CMD lo farà:NET STOP MSSQLSERVER e NET START MSSQLSERVER

Oppure apri "services.msc" e trova "SQL Server (MSSQLSERVER)" e fai clic con il pulsante destro del mouse, seleziona "riavvia".

Questo "di sicuro, di sicuro" ucciderà TUTTE le connessioni a TUTTI i database in esecuzione su quell'istanza.

(Mi piace di più rispetto a molti approcci che cambiano e ripristinano la configurazione sul server/database)

Ecco come eseguire in modo affidabile questo genere di cose in MS SQL Server Management Studio 2008 (potrebbe funzionare anche per altre versioni):

  1. Nell'albero Esplora oggetti, fare clic con il pulsante destro del mouse sul server del database radice (con la freccia verde), quindi fare clic su monitoraggio attività.
  2. Apri la scheda processi nel monitor attività, seleziona il menu a discesa "database" e filtra in base al database desiderato.
  3. Fare clic con il pulsante destro del mouse sul DB in Esplora oggetti e avviare un'attività "Attività -> Metti offline".Lascialo in esecuzione in background mentre...
  4. Spegni in sicurezza tutto ciò che puoi.
  5. Uccidi tutti i processi rimanenti dalla scheda Processo.
  6. Riportare il DB online.
  7. Rinominare il DB.
  8. Riporta il tuo servizio online e indirizzalo al nuovo DB.

L'opzione che funziona per me in questo scenario è la seguente:

  1. Avviare l'operazione "Scollega" sul database in questione.Si aprirà una finestra (in SQL 2005) che mostra le connessioni attive che impediscono azioni sul DB.
  2. Uccidi le connessioni attive, annulla l'operazione di disconnessione.
  3. Il database dovrebbe ora essere disponibile per il ripristino.

Prova questo:

ALTER DATABASE [DATABASE_NAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE

Fare clic con il tasto destro sul nome del database, fare clic su Proprietà per ottenere la finestra delle proprietà, aprire la scheda Opzioni e modificare la proprietà "Limita accesso" da Multiutente a Utente singolo.Quando premi il pulsante OK, ti verrà chiesto di chiudere tutte le connessioni aperte, selezionare "Sì" e sei pronto per rinominare il database....

Questi non hanno funzionato per me (SQL2008 Enterprise), inoltre non sono riuscito a vedere alcun processo in esecuzione o utente connesso al DB.Il riavvio del server (fare clic con il pulsante destro del mouse su SQL Server in Management Studio e selezionare Riavvia) mi ha consentito di ripristinare il DB.

Sto utilizzando SQL Server 2008 R2, il mio DB era già impostato per utente singolo ed era presente una connessione che limitava qualsiasi azione sul database.Così il raccomandato SQLMenace la soluzione ha risposto con un errore. Eccone uno che ha funzionato nel mio caso.

Utilizzo sp_who per ottenere l'elenco di tutti i processi nel database.Questo è meglio perché potresti voler rivedere quale processo uccidere.

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

Risultato
Puoi utilizzare il comando nella colonna KillCommand per terminare il processo che desideri.

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

Puoi utilizzare il comando SP_Who e uccidere tutti i processi che utilizzano il tuo database e quindi rinominare il tuo database.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top