简体   繁体   English

表和临时表之间的差异

[英]Difference between Tables and Temp Tables

why this code work without problem : 为什么这段代码没有问题:

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

Output 产量

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)

but this code does not : 但是这段代码没有:

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

Output 产量

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

what is the difference between Tables and Temp Tables in this code ? 这段代码中的表和临时表有什么区别?

To counter all the other wrong answers, the correct way to test for a #temp table is 要解决所有其他错误答案,测试#temp表的正确方法是

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


Here's an interesting article about compile phase and execution phase fun with #temp tables. 这是一篇关于#temp表的编译阶段和执行阶段乐趣的有趣文章


This is the MSDN reference for Deferred Name Resolution (DNR). 这是延迟名称解析 (DNR)的MSDN参考。 To aid in Stored Procedure creation and statements batches, Deferred Name Resolution was added in SQL Server 7. Prior to that (Sybase), it would have been very hard to create and use tables within a batch without using a lot of dynamic SQL. 为了帮助创建存储过程和批处理语句,在SQL Server 7中添加了Deferred Name Resolution 。在此之前(Sybase),如果不使用大量动态SQL,在批处理中创建和使用表将非常困难。

There are still limitations however, in that if the name does exist, SQL Server will go on and check other aspects of the statements, such as column names of table objects. 但是仍有一些限制,因为如果名称确实存在,SQL Server将继续检查语句的其他方面,例如表对象的列名。 DNR was never expanded to variables or temporary (#)/(##) objects, and when inline table-valued functions were added in SQL Server 2000, DNR was not extended to them either since the purpose of DNRs were only to solve the multi-statement batch issue. DNR从未扩展到变量或临时(#)/(##)对象,并且当在SQL Server 2000中添加内联表值函数时,DNR没有扩展到它们,因为DNR的目的只是解决多个 - 陈述批次问题。 Not to be confused, inline table-valued functions do not support DNR; 不要混淆, 内联表值函数不支持DNR; multi-statement TVFs do. 语种TVF。

The workaround is NOT to use that pattern and instead create the table first and only once. 解决方法是不使用该模式,而是首先创建表,只创建一次。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM