T-SQL: come riconoscere l’esistenza di una tabella temporanea

Sicuramente per qualche mia svista o errore, qualche volta mi è capitato di non riuscire a [ri]creare una tabella temporanea. Con una tabella “normale” (detta anche "user table", per la precisione) non ci sono problemi, basta controllarne la presenza nella vista di sistema sys.objects per eventualmente cancellarla:

IF EXISTS ( SELECT * FROM sys.Objects WHERE Name = 'CLIENTI' )
   DROP TABLE Clienti;
GO

Purtroppo in questo approccio si nasconde un problema: è possibile creare due diverse tabelle che abbiano lo stesso nome (ad esempio: 'CLIENTI'), ma schema diverso (ad esempio 'dbo.CLIENTI' e 'contabilita.CLIENTI'): tralascio ogni considerazione sull’opportunità di tale scelta: può succedere, io di solito evito di farlo, ma mi è capitato di imbattermi in questa situazione. E allora che si fa in questi casi?

Di primo acchito sembrerebbe naturale aggiungere alla clausola WHERE la condizione riguardante lo schema. Peccato che quest’ultimo sia qui presente in forma di ID, normalizzato e in riferimento alla vista sys.schemas:

IF EXISTS ( SELECT *
            FROM sys.Objects
            INNER JOIN sys.schemas
                ON schemas.schema_id = objects.schema_id
               AND schemas.name = 'dbo'
            WHERE Objects.Name = 'CLIENTI'
          )
    DROP TABLE dbo.Clienti;
GO

Ok, funziona; magari non è il massimo della comodità, però funziona!

A dire la verità, un sistema più veloce c’è: basta sfruttare la funzione Object_Id() che restituisce l’identificativo (univoco) dell’oggetto passato come argomento; nello specificare  il nome dell’oggetto possiamo (ma non siamo obbligati a farlo) indicare tutti gli identificativi necessari: Object_Id( '...' ).

Inoltre possiamo passare alla funzione un secondo parametro (opzionale) che specifica il tipo dell’oggetto; per maggiori dettagli si può fare riferimento alla documentazione del campo 'type' della tabella 'sys.objects'

I parametri della funzione sono case-insensitive (considerano allo stesso modo caratteri maiuscoli e minuscoli) sia per il nome, sia per il tipo dell’oggetto.

Sfruttando la funzione Object_Id() possiamo allora riscrivere le istruzioni in questo modo:

IF ( NOT Object_Id( 'dbo.CLIENTI' ) IS NULL )
    DROP TABLE dbo.CLIENTI;
GO

A titolo di cronaca, possiamo anche rinchiudere i nomi entro parentesi quadre, che diventano obbligatorie nel caso in cui il nome contenga caratteri speciali quali lo spazio ' '(prassi che personalmente non condivido, ma al limite chissene…) o il backslash '\' (tipico delle istanze Sql nominate); ad esempio:

IF ( NOT Object_Id( '[SERVER\ISTANZA].[DATABASE].[dbo].[CLIENTI]' , 'u' ) IS NULL )
    DROP TABLE dbo.CLIENTI;
GO

A questo punto, sapendo che le tabelle temporanee vengono create nel database tempdb, possiamo scrivere le istruzioni per la cancellazione di una di esse in questo modo:

IF NOT Object_Id( 'tempdb..#tempTable' ) IS NULL )
    DROP TABLE #tempTable;
GO

L’unica particolarità da notare è che viene omesso il nome dello schema, tra il nome del database e quello della tabella.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*