Controlla se esiste una tabella temporanea ed elimina se esiste prima di creare una tabella temporanea

Sto usando il seguente codice per controllare se la tabella temporanea esiste e rilasciare la tabella se esiste prima di creare nuovamente. Funziona bene finché non cambio le colonne. Se aggiungo una colonna in seguito, verrà visualizzato un errore che dice “colonna non valida”. Per favore fatemi sapere cosa sto facendo male.

IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results CREATE TABLE #Results ( Company CHAR(3), StepId TINYINT, FieldId TINYINT, ) select company, stepid, fieldid from #Results --Works fine to this point IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results CREATE TABLE #Results ( Company CHAR(3), StepId TINYINT, FieldId TINYINT, NewColumn NVARCHAR(50) ) select company, stepid, fieldid, NewColumn from #Results --Does not work 

Non riesco a riprodurre l’errore.

Forse non sto capendo il problema.

Il seguente funziona bene per me in SQL Server 2005, con la colonna extra “pippo” che appare nel secondo risultato di selezione:

 IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results GO CREATE TABLE #Results ( Company CHAR(3), StepId TINYINT, FieldId TINYINT ) GO select company, stepid, fieldid from #Results GO ALTER TABLE #Results ADD foo VARCHAR(50) NULL GO select company, stepid, fieldid, foo from #Results GO IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results GO 

La dichiarazione dovrebbe essere dell’ordine

  1. Modificare la dichiarazione per il tavolo
  2. PARTIRE
  3. Seleziona la dichiarazione.

Senza “GO” in mezzo, l’intera cosa verrà considerata come un singolo script e quando l’istruzione select cerca la colonna, non verrà trovata.

Con ‘GO’, considererà la parte dello script fino a ‘GO’ come un singolo batch e verrà eseguita prima di entrare nella query dopo ‘GO’.

Invece di dropping e ricreare la tabella temporanea, è ansible truncate e riutilizzarla

 IF OBJECT_ID('tempdb..#Results') IS NOT NULL Truncate TABLE #Results else CREATE TABLE #Results ( Company CHAR(3), StepId TINYINT, FieldId TINYINT, ) 

Se si utilizza Sql Server 2016 o Azure Sql Database utilizzare la seguente syntax per eliminare la tabella temporanea e ricrearla. Maggiori informazioni qui MSDN

Sintassi

DROP TABLE [IF EXISTS] [database_name. [nome_schema]. | nome_schema. ] nome_tabella [, … n]

Query:

 DROP TABLE IF EXISTS tempdb.dbo.#Results CREATE TABLE #Results ( Company CHAR(3), StepId TINYINT, FieldId TINYINT, ) 

Penso che il problema è che è necessario aggiungere una dichiarazione GO in mezzo per separare l’esecuzione in lotti. Come il secondo script di rilascio, ad esempio IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results non ha fatto cadere la tabella temporanea facente parte di un singolo batch. Potete per favore provare lo script qui sotto.

 IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results CREATE TABLE #Results ( Company CHAR(3), StepId TINYINT, FieldId TINYINT, ) GO select company, stepid, fieldid from #Results IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results CREATE TABLE #Results ( Company CHAR(3), StepId TINYINT, FieldId TINYINT, NewColumn NVARCHAR(50) ) GO select company, stepid, fieldid, NewColumn from #Results 

Questo ha funzionato per me: social.msdn.microsoft.com/Forums/en/transactsql/thread/02c6da90-954d-487d-a823-e24b891ec1b0?prof=required

 if exists ( select * from tempdb.dbo.sysobjects o where o.xtype in ('U') and o.id = object_id(N'tempdb..#tempTable') ) DROP TABLE #tempTable; 

Solo un piccolo commento da parte mia dato che OBJECT_ID non funziona per me. Lo restituisce sempre

`#tempTable non esiste

.. anche se esiste. Ho appena scoperto che è memorizzato con un nome diverso (suffisso da _ underscore) in questo modo:

#tempTable________

Questo funziona bene per me:

 IF EXISTS(SELECT [name] FROM tempdb.sys.tables WHERE [name] like '#tempTable%') BEGIN DROP TABLE #tempTable; END; 

pmac72 utilizza GO per suddividere la query in batch e utilizzare un ALTER.

Sembra che tu stia eseguendo lo stesso batch ma lo esegui due volte dopo averlo modificato: DROP … CREATE … edit … DROP … CREATE ..

Forse pubblica il tuo codice esatto in modo che possiamo vedere cosa sta succedendo.

Di solito mi colpisce questo errore quando ho già creato la tabella temporanea; il codice che controlla l’istruzione SQL per errori vede la “vecchia” tabella temporanea in atto e restituisce un conteggio errato sul numero di colonne nelle istruzioni successive, come se la tabella temporanea non venisse mai rilasciata.

Dopo aver modificato il numero di colonne in una tabella temporanea dopo aver già creato una versione con meno colonne, rilascia la tabella e THEN esegui la query.

Di recente ho visto un DBA fare qualcosa di simile a questo:

 begin try drop table #temp end try begin catch print 'table does not exist' end catch create table #temp(a int, b int) 

Il mio codice utilizza una tabella di Source che cambia e una tabella di Destination che deve corrispondere a tali modifiche.

 -- -- Sample SQL to update only rows in a "Destination" Table -- based on only rows that have changed in a "Source" table -- -- -- Drop and Create a Temp Table to use as the "Source" Table -- IF OBJECT_ID('tempdb..#tSource') IS NOT NULL drop table #tSource create table #tSource (Col1 int, Col2 int, Col3 int, Col4 int) -- -- Insert some values into the source -- Insert #tSource (Col1, Col2, Col3, Col4) Values(1,1,1,1) Insert #tSource (Col1, Col2, Col3, Col4) Values(2,1,1,2) Insert #tSource (Col1, Col2, Col3, Col4) Values(3,1,1,3) Insert #tSource (Col1, Col2, Col3, Col4) Values(4,1,1,4) Insert #tSource (Col1, Col2, Col3, Col4) Values(5,1,1,5) Insert #tSource (Col1, Col2, Col3, Col4) Values(6,1,1,6) -- -- Drop and Create a Temp Table to use as the "Destination" Table -- IF OBJECT_ID('tempdb..#tDest') IS NOT NULL drop Table #tDest create table #tDest (Col1 int, Col2 int, Col3 int, Col4 int) -- -- Add all Rows from the Source to the Destination -- Insert #tDest Select Col1, Col2, Col3, Col4 from #tSource -- -- Look at both tables to see that they are the same -- select * from #tSource Select * from #tDest -- -- Make some changes to the Source -- update #tSource Set Col3=19 Where Col1=1 update #tSource Set Col3=29 Where Col1=2 update #tSource Set Col2=38 Where Col1=3 update #tSource Set Col2=48 Where Col1=4 -- -- Look at the Differences -- Note: Only 4 rows are different. 2 Rows have remained the same. -- Select Col1, Col2, Col3, Col4 from #tSource except Select Col1, Col2, Col3, Col4 from #tDest -- -- Update only the rows that have changed -- Note: I am using Col1 like an ID column -- Update #tDest Set Col2=S.Col2, Col3=S.Col3, Col4=S.Col4 From ( Select Col1, Col2, Col3, Col4 from #tSource except Select Col1, Col2, Col3, Col4 from #tDest ) S Where #tDest.Col1=S.Col1 -- -- Look at the tables again to see that -- the destination table has changed to match -- the source table. select * from #tSource Select * from #tDest -- -- Clean Up -- drop table #tSource drop table #tDest 

Ora puoi usare la seguente syntax se stai usando una delle nuove versioni di SSMS

 DROP TABLE IF EXISTS schema.yourtable(even temporary tables #...) 

Sì, “colonna non valida” questo errore generato dalla riga “seleziona azienda, stepid, fieldid, NewColumn da #Results”.

Ci sono due fasi di runing t-sql,

Per prima cosa, analizzando, in questa fase il server SQL controlla la correzione della stringa sql inoltrata, inclusa la colonna della tabella, e ottimizza la query per la retreival più veloce.

in secondo luogo, in esecuzione, recupero dei dati.

Se la tabella #Results esiste allora il processo di analisi verificherà che le colonne che hai specificato siano valide o meno, altrimenti (la tabella non esiste) l’analisi verrà eseguita tramite il controllo delle colonne come specificato.

 CREATE TABLE #tempTable (id int IDENTITY(1, 1) PRIMARY KEY, name nvarchar(500), value nvarchar(500)) BEGIN TRY DELETE FROM #tempTable PRINT 'Table deleted' END TRY BEGIN CATCH PRINT 'Table does not exist' END CATCH