Discussione:
Tabelle temporanee
(troppo vecchio per rispondere)
Alessandro
2006-05-18 14:50:51 UTC
Permalink
Salve a tutti,
volevo avere un chiarimento su come vengono effettivamente gestite le
tabelle temporanee globali (##) da SQL Server. A dispetto di quanto scritto
nei BOL (riporto di seguito una parte integrante) la mia esperienza nell'uso
di tali tabelle mi porta a dire che indipendentemente dal fatto che la
tabella temporanea sia stata usata da n connessioni (per insert, update o
select) la tabella verrà comunque cancellata nel momento in cui la
connessione che l'ha create viene chiusa (al limite se in quel momento la
tabella è loccata la cancellazione viene ritardata fino all'eliminazione dei
lock).

I BOL dicono:
"Ad esempio, se si crea una tabella denominata employees, la tabella può
essere utilizzata da chiunque disponga delle autorizzazioni di protezione
nel database per utilizzarla fino a quando non viene eliminata. Se si crea
una tabella temporanea locale denominata #employees, la tabella può essere
utilizzata soltanto dall'utente che l'ha creata e verrà eliminata alla
chiusura della connessione di tale utente. Se si crea una tabella temporanea
globale denominata ##employees, tutti gli utenti del database possono
utilizzare tale tabella. Se la tabella non viene utilizzata da altri utenti
dopo che è stata creata, verrà eliminata alla chiusura della connessione
dell'utente che l'ha creata. Se la tabella viene utilizzata da altri utenti
dopo che è stata creata, verrà eliminata quando tutti gli utenti chiuderanno
la connessione."

Da quanto scritto nei BOL (ho controllato anche nella versione inglese per
vedere se poteva essere un problema di traduzione) sembra che la tabella
temporanea globale, se utilizzata da n connessioni, dovrebbe essere
cancellata solamente alla disconnessione di tutte le n connessioni.
C'è un errore nei BOL oppure sbaglio io qualcosa nella gestione delle
tabelle temporanee globali?


GRAZIE,
Alessandro
Lorenzo Benaglia
2006-05-18 15:36:01 UTC
Permalink
Post by Alessandro
volevo avere un chiarimento su come vengono effettivamente gestite le
tabelle temporanee globali (##) da SQL Server. A dispetto di quanto
scritto nei BOL (riporto di seguito una parte integrante) la mia
esperienza nell'uso di tali tabelle mi porta a dire che
indipendentemente dal fatto che la tabella temporanea sia stata usata
da n connessioni (per insert, update o select) la tabella verrà
comunque cancellata nel momento in cui la connessione che l'ha create
viene chiusa (al limite se in quel momento la tabella è loccata la
cancellazione viene ritardata fino all'eliminazione dei lock).
Ciao Alessandro,

L'argomento è un po' delicato:
I BOL affermano che "Se la tabella viene utilizzata da altri utenti dopo che
è stata creata, verrà eliminata quando tutti gli utenti chiuderanno la
connessione."

In realtà la tabella verrà eliminata quando non sarà più utilizzata da una
transazione ad opera di connessioni diverse da quella che l'ha generata.

la verifica è presto fatta. Apri in QA o SSMS 2 connessioni ed incolla i
seguenti script:

/* Connessione 1 */
CREATE TABLE dbo.##Utenti(
UtenteID int NOT NULL IDENTITY(1, 1),
Operatore varchar(30) NOT NULL,
Nome varchar(30) NOT NULL,
Cognome varchar(30) NOT NULL,
CONSTRAINT PK_Utenti PRIMARY KEY(UtenteID),
CONSTRAINT UN_Operatore UNIQUE(Operatore)
);
GO

------------------------------------------------

/* Connessione 2 */
BEGIN TRAN
INSERT ##Utenti VALUES('Operatore 1', 'Lorenzo', 'Benaglia');

/* Aspetto 5 secondi */
WAITFOR DELAY '00:00:05';

/* Verifico se esiste ancora la tabella ##Utenti */
IF OBJECT_ID('tempdb.dbo.##Utenti') IS NULL
PRINT '1 - La tabella non esiste più.'
ELSE
PRINT '1 - La tabella esiste ancora.';

INSERT ##Utenti VALUES('Operatore 2', 'Luca', 'Bianchi');

/* Aspetto 5 secondi */
WAITFOR DELAY '00:00:05';

/* Verifico se esiste ancora la tabella ##Utenti */
IF OBJECT_ID('tempdb.dbo.##Utenti') IS NULL
PRINT '2 - La tabella non esiste più.'
ELSE
PRINT '2 - La tabella esiste ancora.';

INSERT ##Utenti VALUES('Operatore 3', 'Andrea', 'Montanari');

/* Aspetto 5 secondi */
WAITFOR DELAY '00:00:05';

/* Verifico se esiste ancora la tabella ##Utenti */
IF OBJECT_ID('tempdb.dbo.##Utenti') IS NULL
PRINT '3 - La tabella non esiste più.'
ELSE
PRINT '3 - La tabella esiste ancora.';

COMMIT TRAN;

/* Verifico se esiste ancora la tabella ##Utenti */
IF OBJECT_ID('tempdb.dbo.##Utenti') IS NULL
PRINT '4 - La tabella non esiste più.'
ELSE
PRINT '4 - La tabella esiste ancora.';
GO

/* Output:


(1 row(s) affected)
1 - La tabella esiste ancora.

(1 row(s) affected)
2 - La tabella esiste ancora.

(1 row(s) affected)
3 - La tabella esiste ancora.
4 - La tabella non esiste più.

*/

1) Lancia il primo script nella connessione 1 e genera la tabella .##Utenti;
2) Lancia il secondo script e mentre è in esecuzione chiudi la prima
connessione.

Quando la transazione sarà conclusa, la tabella verrà eliminata.
Post by Alessandro
C'è un errore nei BOL oppure sbaglio io qualcosa nella gestione delle
tabelle temporanee globali?
Mah... diciamo che c'è una imprecisione.
Post by Alessandro
GRAZIE,
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo
http://italy.mvps.org
Loading...