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

Ric*_*rdo 6 t-sql sql-server sql-server-2012

下面的 tSQL 查询令我困惑:

select 1 as FIELD into #TEMP
drop table #TEMP
select 1 as FIELD into #TEMP
Run Code Online (Sandbox Code Playgroud)

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

消息 2714,级别 16,状态 1,第 3 行
数据库中已经有一个名为“#TEMP”的对象。

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

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

我的问题:

  1. 为什么会发生错误?
  2. 如何修复查询以使其按预期执行?

附注。上面的查询是我的真实世界查询的简化,它显示了相同的症状。

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

shA*_*A.t 2

我发现现有表的查找是不同的:

select 1 as FIELD into #TEMP
drop table #TEMP
Run Code Online (Sandbox Code Playgroud)

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

select 1 as FIELD into #TEMP
Run Code Online (Sandbox Code Playgroud)

错误是:

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

当您在这些命令后使用selecton时:#TEMP

select * from #TEMP
Run Code Online (Sandbox Code Playgroud)

错误是:

对象名称“#TEMP”无效。

因此,在第一种情况下,存在一个具有#TEMP名称的对象,而在另一种情况下,则不存在具有#TEMP名称的对象!

一个重要的注释technet.microsoft是:

DROP TABLE 和 CREATE TABLE 不应在同一批处理中的同一表上执行。否则可能会出现意外错误。


在通过 SQL Server 数据库引擎删除表的注释中:

SQL Server 数据库引擎将实际的页释放及其关联的锁推迟到事务提交之后。

因此,using 语句上的第二个错误select可能与实际的页释放有关,而 using 语句上的第一个错误可能与关联锁到事务提交之间的持续时间into有关。