Lorenzo Benaglia


Storie di un SQLlaro mannaro...
Archivio Posts
Anno 2010

Anno 2009

Anno 2008

Anno 2007

Anno 2006

Anno 2005
Calendario
aprile 2024
lmmgvsd
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

E ammazziamo queste connessioni!!

Oggi un mio collega mi ha posto un quesito al quale risposi tempo fa su microsoft.public.it.sql: "Sai un metodo per killare tutti i processi in una botta sola?"

Sappiamo tutti che SQL Server permette di terminare una connessione ed internamente tutte le transazioni associate tramite la funzione KILL, specificando come argomento il ProcessID.

A volte può essere comodo chiudere tutte le connessioni ad un database in una volta sola, senza la necessità di rendere lo stato permanente mediante il comando:

ALTER DATABASE [nome db]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE


Purtroppo SQL Server non offre una simile funzionalità, però nessuno ci vieta di aguzzare l'ingegno
Le stored procedure di sistema sp_who e sp_who2 (non documentata) ci forniscono diverse informazioni sugli utenti e le conessioni attive, così ho pensato di utilizzare queste procedure per definire una nuova stored procedure che in base al database passato come argomento, chiude tutte le connessioni attive ad esso ad esclusione di quella corrente:

USE tempdb 
GO

/* Creo la Stored Procedure dbo.up_CloseSessions */ 
CREATE PROCEDURE dbo.up_CloseSessions( 
@dbname nchar(128) 
) 
AS 
/* Processo corrente */
DECLARE @spid smallint

/* Statement SQL */
DECLARE @strSQL varchar(10)

/* Creo la tabella temporanea dbo.#tmpProcesses */ 
CREATE TABLE dbo.#tmpProcesses( 
spid smallint, 
ecid smallint, 
status nchar(30), 
loginame nchar(128), 
hostname nchar(128), 
blk char(5), 
dbname nchar(128), 
cmd nchar(16) 
) 

/* La popolo */ 
INSERT dbo.#tmpProcesses 
EXEC sp_who

/* Dichiaro il cursore */ 
DECLARE curKill CURSOR FOR 
SELECT spid 
FROM dbo.#tmpProcesses 
WHERE dbname = @dbname AND 
spid <> @@spid

/* Apro il cursore */ 
OPEN curKill

/* Prima lettura */ 
FETCH NEXT FROM curKill 
INTO @spid

/* Loop */ 
WHILE @@FETCH_STATUS = 0
BEGIN
    /* Chiudo la sessione corrente */
    SET @strSQL = 'KILL ' + CAST(@spid AS varchar)
    EXEC (@strSQL)

    /* Letture successive */
    FETCH NEXT FROM curKill
    INTO @spid
END

/* Dealloco e chiudo il cursore */ 
CLOSE curKill 
DEALLOCATE curKill 
GO 


E' possibile verificarne il funzionamento aprendo ad esempio 5 o 6 connessioni al database Northwind tramite il Query Analyzer ed eseguendo il seguente script:

/* Visualizzo i processi attivi */ 
EXEC sp_who 
GO

/* Disconnetto tutti gli utenti 
** (tranne me) da Northwind 
*/ 
EXEC dbo.up_CloseSessions 'Northwind' 
GO

/* Visualizzo i processi attivi */ 
EXEC sp_who 
GO 


Se preferite potete definire la stored procedure direttamente nel database master in modo che sia sempre disponibile
Categoria: SQL Server
giovedì, 08 set 2005 Ore. 14.41
Statistiche
  • Views Home Page: 932.108
  • Views Posts: 698.125
  • Views Gallerie: 12.633.623
  • n° Posts: 300
  • n° Commenti: 314
Mappa





















Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003