检查临时表是否存在,并在创build临时表之前删除它(如果存在)

我正在使用下面的代码来检查临时表是否存在,并删除表,如果它存在之前再次创build。 只要我不改变列,它工作正常。 如果我稍后添加一列,它会给出一个错误说“无效列”。 请让我知道我做错了什么。

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 

我无法重现错误。

也许我不了解这个问题。

在SQL Server 2005中,以下工作正常,在第二个select结果中出现额外的“foo”列:

 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 

声明应该是有序的

  1. 更改表格的声明
  2. select语句。

如果没有之间的“GO”,整个事情将被视为一个单一的脚本,当select语句查找列,它不会被发现。

使用'GO'时,会将'GO'部分视为一个批次,并在'GO'后进入查询。

而不是dropping和重新创build临时表,你可以truncate和重用它

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

如果您正在使用Sql Server 2016Azure Sql Database则使用以下语法删除临时表并重新创build它。 更多信息在这里MSDN

句法

DROP TABLE [IF EXISTS] [database_name。 [schema_name]。 | schema_name。 ] table_name [,… n]

查询:

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

这工作对我来说: 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; 

因为OBJECT_ID对我不起作用,所以我只是稍微评论一下。 它总是返回

`#tempTable不存在

尽pipe它确实存在。 我只是发现它存储在不同的名称(后缀_下划线)如下所示:

#tempTable________

这适用于我:

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

pmac72正在使用GO将查询分解成批次并使用ALTER。

您似乎正在运行相同的批次,但更改后运行它两次:DROP … CREATE …编辑… DROP … CREATE ..

也许发布你的确切代码,所以我们可以看到发生了什么事情。

我认为问题是你需要在两者之间joinGO语句来将执行分成批次。 作为第二个下降脚本,即IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results没有删除作为单个批处理的一部分的临时表。 你可以请尝试下面的脚本。

 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 

我通常在创build临时表时遇到这个错误; 检查SQL语句错误的代码会看到“旧”临时表,并在稍后的语句中返回错误计数,就像临时表从未被删除一样。

在创build了一个较less列的版本后,在更改了临时表中的列数之后,请删除该表,然后运行您的查询。

我的代码使用更改的Source表和一个必须匹配这些更改的Destination表。

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

我最近看到一个DBA做类似这样的事情:

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

现在,如果您正在使用SSMS的新版本之一,则可以使用以下语法

 DROP TABLE IF EXISTS schema.yourtable(even temporary tables #...) 
 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