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

5

我试图执行存储过程,但遇到一个已存在的临时表问题,但我只创建了一次并在代码的另一个部分使用。

SELECT ...
INTO #tmpUnidadesPresupuestadas 
FROM proce.table1 

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

我收到了这个消息:

数据库中已经存在一个名为 '#tmpUnidadesPresupuestadas' 的对象。

我该如何解决呢? 谢谢!


如果您先创建表并插入数据,那么使用SELECT INTO语句会有所不同。而且,使用SELECT INTO语句创建的临时表是可丢弃的。 - RoMEoMusTDiE
在选择临时表之前先删除它。 - Gordon Linoff
7个回答

10

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

DROP TABLE IF EXISTS #tmpUnidadesPresupuestadas

如果在 SQL Server 2016 之前,则可以这样删除:

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

9

没有看到更多的代码,无法确定以下情况是否是你的问题,但可能是。

当您有互斥的代码分支都对同一临时表执行SELECT...INTO操作时,可能会出现错误。SELECT...INTO操作会使用填充数据的查询创建具有结构的表。如果出现两次以上,则解析器会认为这是一个错误,因为您不能在已有数据的情况下重新创建表的结构。

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

虽然显然没有太大意义,但这就显示了问题。这两条路径是互相排斥的,但解析器认为它们可能都会执行,并发出致命错误。你可以扩展它,将每个分支包装在BEGIN...END中,并添加drop table(无论是否有条件), 但解析器仍然会报错。

公平地说,实际上两条路径都可能被执行,如果有一个循环或GOTO使得一次@Debug = 1,另一次不是,那么对于解析器来说可能要求过高了。不幸的是,我不知道有什么解决方法,使用INSERT INTO而不是SELECT INTO是我知道避免这个问题唯一的方法,即使在一个特别列重的查询中这可能会非常麻烦。


1
好的 - 我确实想到了一个非常糟糕的解决方法,为了完整起见,我会提供它。您可以动态构建SELECT...INTO SQL语句。解析器无法在编译时访问它,因此您不会收到错误。 - RBerman
非常感谢,我正在做这个,但是我没有在任何地方找到这样简单的解释,这让我很疯狂。 - Uttam

1

我有点不清楚你的意图。我猜想你现在不想删除这个表。我认为你可能在寻找的语法是Insert Into。

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

如果您确实希望删除该表,前面的答案已经涵盖了这一点。

1

1
确保存储过程和表名不相同。

对我来说,它是一个与表格同名的同义词。 - frmbelz

0

添加逻辑以删除存在的内容。很可能您之前已经运行过它。该表仍然保留在存储过程的上一次运行中。如果您注销然后重新登录并运行它,那很可能会清除它。但最干净的方法是检查其是否存在并在存在时将其删除。我假设这是MsSql。


0

首先,您应该检查临时表是否已经存在,如果是,则删除它,然后创建一个空表,接着使用插入语句。请参考下面的示例。

 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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接