临时表解析-SQL错误-需要解释
我有以下无法执行的代码。我不是在到处找工作。我想了解SQL在做什么,以及为什么它会出错:“数据库中已经有一个名为“#t”的对象。”请注意解释临时表解析-SQL错误-需要解释,sql,sql-server,temp-tables,Sql,Sql Server,Temp Tables,我有以下无法执行的代码。我不是在到处找工作。我想了解SQL在做什么,以及为什么它会出错:“数据库中已经有一个名为“#t”的对象。”请注意解释 如果object_id('tempdb.dbo.#t')不是null 升降台 去 声明@i int=0 如果@i=0 创建表#t(col1 int) 其他的 创建表#t(col1 int) 我建议对临时表使用不同的名称 至少如果您确实需要在if和ELSE中创建临时表 或者在开始时,在IF之前,只拖放并创建一次临时表 遗憾的是,编译器对这样一件小事感到困惑。
如果object_id('tempdb.dbo.#t')不是null
升降台
去
声明@i int=0
如果@i=0
创建表#t(col1 int)
其他的
创建表#t(col1 int)
我建议对临时表使用不同的名称
至少如果您确实需要在if
和ELSE
中创建临时表
或者在开始时,在IF
之前,只拖放并创建一次临时表
遗憾的是,编译器对这样一件小事感到困惑。当解析和计算T-Sql时,它会忽略控制流语句,如
IF
因此,相同临时表的创建在相同的范围内,并作为重复对象问题进行评估 解决方案示例:
declare @i int = 0
if @i = 0
begin
if object_id('tempdb..#t1') is not null
drop table #t1;
create table #t1 (col1 int);
end
else
begin
if object_id('tempdb..#t2') is not null
drop table #t2;
create table #t2 (col1 int, col2 int);
end
如果您为正在使用的特定DBMS添加标记和标记,这将非常有用。我刚刚问过这就是你想要执行的脚本吗?不,这是完整脚本的简化。完整的脚本毫无意义。这是编译工作方式的一个限制。有条件地创建临时表充满了危险,因为优化器确实需要知道表是否在那里(及其模式),以便为引用它的语句生成执行计划,因此
#t
在任何地方都被视为“相同”表,因此不允许重复的CREATE
s(和其他不兼容的DDL语句一样)。首先,不要这样做。保持临时表方案不变,不要有条件地创建它们。FWIW,您可以有条件地更改它们。请检查代码并尝试运行。它不会编译。错误是:“数据库中已经有一个名为“#t”的对象。”我得到的也是一样。这是一个限制。动态SQL也不会工作,因为#tmp将在新会话中创建并立即丢失。到目前为止,它是TEMPDB中一种不需要的编译行为,导致了一个错误,因为SQL提供的错误既不正确也不真实。谢谢Luk。我最终在代码中做了类似的事情。但没有寻找workaround。想了解SQL返回无效消息并出现错误行为的原因。到目前为止,这是因为编译器在TEMPDB中被混淆并出现错误。如果在用户表中创建表,则不会发生这种情况(#被删除)也没有找到官方的原因。只是旧的SO帖子。谢谢Luk。是的。看起来那个家伙有类似的问题。有解决办法。只是想了解到底发生了什么。谢谢。
declare @i int = 0
if @i = 0
begin
if object_id('tempdb..#t1') is not null
drop table #t1;
create table #t1 (col1 int);
end
else
begin
if object_id('tempdb..#t2') is not null
drop table #t2;
create table #t2 (col1 int, col2 int);
end