为什么DROP TABLE似乎没有在SELECT INTO之前生效?

时间:2015-03-09 14:17:15

标签: sql-server tsql sql-server-2012

以下tSQL查询令我感到困惑:

select 1 as FIELD into #TEMP
drop table #TEMP
select 1 as FIELD into #TEMP

当我从SQL Server Management Studio会话窗口运行它时(按 F5 到整个查询,作为一个组),我收到以下错误:

  

Msg 2714,Level 16,State 1,Line 3
  已有一个名为' #TEMP'在数据库中。

请注意,在执行查询之前,表#TEMP不存在。

我认为代码不应该产生任何错误,因为第2行正在删除临时表。但是,当执行第3行时,就好像下降没有生效。

我的问题:

  1. 为什么会发生错误?
  2. 如何修复查询以使其按预期执行?
  3. PS。上面的查询是对我的现实世界查询的简化,显示了相同的症状。

    PS2。无论这是否是一种合理的编程实践(正如Sean在他的评论中所暗示的那样),这种意外行为促使我寻找有关如何解析这些查询的信息,希望这些知识将来对我有所帮助。

2 个答案:

答案 0 :(得分:2)

这里试试这个:

select 1 as FIELD into #TEMP
drop table #TEMP
GO
select 1 as FIELD into #TEMP

答案 1 :(得分:2)

正如我发现现有表的搜索不同:

select 1 as FIELD into #TEMP
drop table #TEMP

在这些命令后使用into语句时:

select 1 as FIELD into #TEMP

错误是:

  

数据库中已经有一个名为'#TEMP'的对象。

在这些命令之后select使用#TEMP时:

select * from #TEMP

错误是:

  

无效的对象名称'#TEMP'。

所以,在第一种情况下,THERE是一个名为#TEMP的对象,而在另一种情况下,THERE不是一个名为#TEMP的对象!。

technet.microsoft的重要提示是:

  

不应在同一批次的同一个表上执行DROP TABLE和CREATE TABLE。否则可能会发生意外错误。


在SQL Server数据库引擎删除表的说明中:

  

SQL Server数据库引擎推迟实际的页面解除分配及其关联的锁定,直到事务提交为止。

因此,使用select语句的第二个错误可能与实际页面解除分配有关,使用into语句时的第一个错误可能与锁定之间的持续时间有关在事务提交之前关联