表和临时表之间的差异

Nea*_*ack 7 sql t-sql sql-server

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

drop table t1 
select * into t1 from  master..spt_values
drop table t1 
select * into t1 from  master..spt_values
Run Code Online (Sandbox Code Playgroud)

产量

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)
Run Code Online (Sandbox Code Playgroud)

但是这段代码没有:

drop table #t1 
select * into #t1 from  master..spt_values
drop table #t1 
select * into #t1 from  master..spt_values
Run Code Online (Sandbox Code Playgroud)

产量

Msg 2714, Level 16, State 1, Line 4
There is already an object named '#t1' in the database.
Run Code Online (Sandbox Code Playgroud)

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

Ric*_*iwi 4

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

if object_id('tempdb..#temp') is not null
   drop table #temp;
Run Code Online (Sandbox Code Playgroud)


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


这是延迟名称解析(DNR) 的 MSDN 参考。为了帮助存储过程创建和语句批处理,Deferred Name Resolution在 SQL Server 7 中添加了此功能。在此之前 (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; 
Run Code Online (Sandbox Code Playgroud)