表格和临时表格之间的区别

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

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.

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


为了对付所有其他错误的答案,测试#temp表的正确方法是

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


这里有一篇关于#temp表编译阶段和执行阶段的有趣文章。


这是延迟名称解析(DNR)的MSDN参考。 为了帮助存储过程创建和语句批处理,在SQL Server 7中添加了Deferred Name Resolution 。在此之前(Sybase),在批处理中创建和使用表而不使用大量动态SQL是非常困难的。

但是,仍然有一些限制,如果名称确实存在,SQL Server将继续并检查语句的其他方面,例如表对象的列名称。 DNR从来没有扩展到变量或临时(#)/(##)对象,并且当在SQL Server 2000中添加了内联表值函数时,由于DNR的目的仅仅是解决multi - 语句批处理问题。 不要混淆, 内联表值函数不支持DNR; 多语句 TVFs。

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

-- 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; 
链接地址: http://www.djcxy.com/p/65733.html

上一篇: Difference between Tables and Temp Tables

下一篇: check if selected row is last visible row in table