表和临时表之间的差异

时间:2012-11-05 10:13:25

标签: sql sql-server tsql

为什么这段代码没有问题:

drop table t1 
select * into t1 from  master..spt_values
drop table t1 
select * into t1 from  master..spt_values

输出

Msg 3701, Level 11, State 5, Line 1
Cannot drop the table 't1', because it does not exist or you do not have permission.

(2508 row(s) affected)

(2508 row(s) affected)

但是这段代码没有:

drop table #t1 
select * into #t1 from  master..spt_values
drop table #t1 
select * into #t1 from  master..spt_values

输出

Msg 2714, Level 16, State 1, Line 4
There is already an object named '#t1' in the database.

此代码中的表和临时表有什么区别?

1 个答案:

答案 0 :(得分:4)

要解决所有其他错误答案,测试#temp表的正确方法是

if object_id('tempdb..#temp') is not null
   drop table #temp;

<小时/> 这是#{3}}关于#temp tables的编译阶段和执行阶段的乐趣。

<小时/> 这是interesting article(DNR)的MSDN参考。为了帮助创建存储过程和批处理语句,在SQL Server 7中添加了Deferred Name Resolution。在此之前(Sybase),如果不使用大量动态SQL,在批处理中创建和使用表将非常困难。 。

但是仍有一些限制,因为如果名称存在,SQL Server将继续检查语句的其他方面,例如表对象的列名。 DNR从未扩展到变量或临时(#)/(##)对象,并且当在SQL Server 2000中添加内联表值函数时,DNR没有扩展到它们,因为DNR的目的只是解决多个 - 陈述批次问题。不要混淆,内联表值函数不支持DNR; 多语句 TVF。

解决方法不是使用该模式,而是首先创建表,只创建一次。

-- drop if exists
if object_id('tempdb..#t1') is not null
   drop table #t1; 
-- create table ONCE only
select * into #t1 from master..spt_values where 1=0;
-- .... 
-- populate
insert #t1
select * from master..spt_values
-- as quick as drop
truncate table #t1; 
-- populate
insert #t1
select * from master..spt_values
-- as quick as drop
truncate table #t1; 

-- clean up
drop table #t1;