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

时间:2017-05-15 22:13:47

标签: sql sql-server stored-procedures

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

SELECT ...
INTO #tmpUnidadesPresupuestadas 
FROM proce.table1 

--Insertar in table src..
INSERT INTO table (
 ....) 
SELECT
....
FROM
    #tmpUnidadesPresupuestadas

我收到此消息:

  

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

我该如何解决?此致

7 个答案:

答案 0 :(得分:4)

临时表适用于整个当前会话。如果您不止一次运行此语句,那么该表将已存在。要么检测并截断它,要么在选择drop之前检查它是否存在:

DROP TABLE IF EXISTS #tmpUnidadesPresupuestadas

如果在SQL Server 2016之前,则按原样删除:

IF OBJECT_ID('tempdb.dbo.#tmpUnidadesPresupuestadas', 'U') IS NOT NULL
  DROP TABLE #tmpUnidadesPresupuestadas; 

答案 1 :(得分:4)

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

当您的代码互斥的分支都对同一个临时表执行SELECT ... INTO时,缺陷将导致此错误。临时表的SELECT ... INTO创建具有用于填充表的查询结构的表。解析器假定该错误是否发生两次,这是一个错误,因为一旦表已经有数据就无法重新创建表的结构。

if @Debug=1
    select * into #MyTemp from MyTable;
else
    select * into #MyTemp from MyTable;

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

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

答案 2 :(得分:1)

我对你的尝试有点不清楚。我想你现在不想放弃这张桌子。我相信你可能正在寻找的语法是 插入

Insert into #tmpUnidadesPresupuestadas (Col1, col2, ... colN)
Select firstcol, secondcol... nthCol 
From Data

如果您确实希望放弃该表,那么之前的答案已经涵盖了。

答案 3 :(得分:0)

这对其他人可能有用,请记住,如果在单个存储过程或批处理中创建了多个临时表,则它们必须具有不同的名称。如果使用相同的名称,将无法更改该过程。

https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2012/ms174979(v=sql.110)#temporary-tables

答案 4 :(得分:0)

确保存储过程和表的名称不同。

答案 5 :(得分:0)

首先,应该检查临时表是否已经存在(如果存在),然后删除它,然后创建一个空表,然后使用insert语句。请参阅下面的示例。

 IF OBJECT_ID('tempdb..#TmpTBL') IS NOT NULL
        DROP TABLE #TmpTBL;

SELECT TOP(0) Name , Address,PhoneNumber 
INTO #TmpTBL
FROM EmpDetail 

if @Condition=1
    INSERT INTO #TmpTBL (Name , Address,PhoneNumber) 
    SELECT Name , Address,PhoneNumber FROM EmpDetail;
else
    INSERT INTO #TmpTBL (Name , Address,PhoneNumber) 
    SELECT Name , Address,PhoneNumber FROM EmpDetail;

答案 6 :(得分:-1)

添加逻辑以删除(如果存在)。很可能你以前跑过它。该表保留在先前运行的存储过程中。如果您注销并登录然后运行它,那很可能会清除它。但最干净的方法是检查它是否存在并删除它。我假设这是MsSql。