【发布时间】:2015-03-09 14:17:14
【问题描述】:
下面的 tSQL 查询让我很困惑:
select 1 as FIELD into #TEMP
drop table #TEMP
select 1 as FIELD into #TEMP
当我从 SQL Server Management Studio 会话窗口运行它时(按 F5 到整个查询,作为一个组),我收到以下错误:
消息 2714,第 16 级,状态 1,第 3 行
数据库中已经有一个名为“#TEMP”的对象。
请注意,在执行查询之前,表 #TEMP 不存在。
我认为代码不应该产生任何错误,因为第 2 行正在删除临时表。但是当执行第 3 行时,就好像 drop 没有生效。
我的问题:
- 为什么会发生错误?
- 如何修复查询以使其按预期执行?
PS。上面的查询是我的真实世界查询的简化,它显示了相同的症状。
PS2。不管这是否是一种合理的编程实践(正如 Sean 在他的 cmets 中暗示的那样),这种意想不到的行为促使我寻找有关如何解析这些查询的信息,希望这些知识将来对我有所帮助。
【问题讨论】:
-
这与 sql 编译器和解析器的工作方式有关。我的问题是,为什么世界上单个过程中的临时表会有相同的名称???这听起来像是让我感到困惑的秘诀。
-
您可以在第一个
drop table之后添加GO以指示批处理的结束,但如果这实际上是存储过程的一部分,它将不起作用,即使它是 不在存储过程中,Sean 的 cmets 仍然适用。 -
@Sean - 这是一个很好的观点。实际上,这就是我最终要做的——为临时表使用不同的名称。但我对这个问题很感兴趣,这就是我问的原因。
-
@Sean - 我虽然 INSERT INTO 会在运行时解决 #TEMP 对象的存在,但事实并非如此,是吗?一位同事暗示可能会在编译时解析对象,但我不明白在这种情况下它是如何工作的。你有什么暗示为什么会这样吗?
标签: sql-server tsql sql-server-2012