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

Ger*_*rdo 5 sql sql-server stored-procedures

我正在尝试执行存储过程,但我遇到了现有时态表的问题,但我只是创建了一次并用于另一部分代码

SELECT ...
INTO #tmpUnidadesPresupuestadas 
FROM proce.table1 

--Insertar in table src..
INSERT INTO table (
 ....) 
SELECT
....
FROM
    #tmpUnidadesPresupuestadas
Run Code Online (Sandbox Code Playgroud)

我收到这条消息:

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

我该如何解决?问候

Don*_*nie 9

一个临时表存在于整个当前会话中。如果您多次运行此语句,则该表已经存在。要么检测它并截断它,要么在drop它存在之前选择它:

DROP TABLE IF EXISTS #tmpUnidadesPresupuestadas
Run Code Online (Sandbox Code Playgroud)

如果在 SQL Server 2016 之前,则删除如下:

IF OBJECT_ID('tempdb.dbo.#tmpUnidadesPresupuestadas', 'U') IS NOT NULL
  DROP TABLE #tmpUnidadesPresupuestadas; 
Run Code Online (Sandbox Code Playgroud)


小智 7

如果没有看到更多代码,就不可能知道以下情况是否是您的问题,但可能是。

当您有对同一个临时表执行 SELECT...INTO 的互斥代码分支时,缺陷会导致此错误。SELECT...INTO 到临时表使用用于填充它的查询结构创建表。解析器假设如果出现两次,这是一个错误,因为一旦它已经有数据,你就不能重新创建表的结构。

if @Debug=1
    select * into #MyTemp from MyTable;
else
    select * into #MyTemp from MyTable;
Run Code Online (Sandbox Code Playgroud)

虽然显然意义不大,但仅此一项就可以说明问题。这两条路径是互斥的,但解析器认为它们都可能被执行,并发出致命错误。您扩展它,将每个分支包装在 BEGIN...END 中,并添加删除表(有条件或无条件),解析器仍然会给出错误。

公平地说,实际上这两条路径都可以执行,如果有一个循环或 GOTO 以便一次在 @Debug = 1 附近,而另一次则没有,所以它可能对解析器要求太多。不幸的是,我不知道有什么解决方法,并且使用 INSERT INTO 而不是 SELECT INTO 是我知道的避免该问题的唯一方法,即使在特别繁重的查询中命名所有列可能非常麻烦。