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

时间:2011-12-15 07:19:07

标签: sql sql-server-2005

Alter Procedure sp_Member(
  @comcode int = 0,
  @SubComCode int = 0
)
as begin
  set nocount on
  If @comcode='0'
  begin
    select (
      select sum(amount)
        from tbcoudet
        where memcode=tbm.memcode and
              expyear=(select max(expyear) from tbexpyear)
              and exists (
                select itemcode
                from tbitem
                where comcode=@comcode and
                  SubComCode=@SubComCode and
                  itemcode=tbcoudet.itemcode
              )
        group by memcode,expyear
      )'TurnOver', *
    into #result from tbmember tbm where can_flag='N'
  end
  If @subcomcode='0'
  begin
    select (
      select sum(amount)
      from tbcoudet
      where memcode=tbm.memcode and expyear=(select max(expyear) from tbexpyear)
        and exists (
          select itemcode
          from tbitem
          where comcode=@comcode and
            itemcode=tbcoudet.itemcode
        )
      group by memcode,expyear
    )'TurnOver', *
    into #result from tbmember tbm where can_flag='N'
  end

  select top 10 * from #result where TurnOver is not null order by TurnOver desc
end

这是我的sql代码,当我要执行存储过程时,我得到错误

There is already an object named '#result' in the database.

谁能告诉我这是什么问题?

6 个答案:

答案 0 :(得分:9)

错误是:该名称已经有一个临时表 - 如果它已经存在,请不要重新创建它....

问题在于你选择的方式 - 你有两个地方

select (columns)
into #result 
from tbmember tbm 
...

第一次,这将创建临时表#result。第二次,你会得到错误 - 因为它无法创建一个已经存在的表。

因此您需要将代码更改为:

  • 在开头

    中明确创建表#result
    CREATE TABLE #result ( ...give list of columns and their datatypes here .....)
    
  • 使用这样的代码插入值:

    INSERT INTO #result(colum list)
       SELECT (column list) 
       FROM  .......
       WHERE .......
    

该代码将起作用,您将能够在临时表中插入两组数据。

答案 1 :(得分:4)

SELECT ... INTO ...始终要创建 临时表。

而是在过程的顶部创建临时表(使用create table #result (columns)),然后使用INSERT INTO (columns) SELECT ...重新编写选择。

我无法写出完整的示例,因为我不知道您的列定义。

即使,当然,只有一个if语句是真的,T-SQL解析器相当简单,仍然“看到”两个尝试声明#result


顺便说一句,我不确定你为什么写这样的if陈述:

if @subcomcode='0'

由于@subcomcode是一个整数,因此最好不要引用0字面值。

答案 2 :(得分:4)

如果您不确定临时表是否存在,但您确信在下一个语句之前您不需要它以这种方式使用object_id function

if object_id('tempdb..#result', 'u') is not null
    drop table #result

如果表不存在则不会导致错误,如果表不存在则丢弃它。在我看来,在每个之前使用它是一个很好的做法:

select ... into #temp from ...

答案 3 :(得分:0)

同意在创建新临时表之前删除它是件好事。但是一个简单的解决方法就是在调试这种类型的东西时关闭数据库连接。断开连接 - 擦除所有那些给你。

答案 4 :(得分:0)

我有类似的问题,但这里没有提出的解决方案对我有帮助。我在存储过程中有6个类似于这两个的ifs并且它不会让我改变程序,这没有任何意义,它显然可以工作。在alter procedure上引发相同的错误。我必须在每个if中都有#tbl因为每个if都选择了不同的列而我不想为每个选择制作表。其他选项是动态选择......

我必须让它变得动态(不是全部),就像这样:

IF @Type = '1'
    SELECT
        col1
    INTO #tbl1
    FROM Table1
ELSE IF @Type = '2'
    SELECT
        col1
        ,col2
    INTO #tbl2
    FROM Table2
--IF...

DECLARE @sql VARCHAR(MAX) = '
    select 
        *
    from #tbl' + @Type

EXEC (@sql)

但在你的情况下,你应该手动创建临时表,因为你使用相同的结构,只是添加值。

如果您懒于创建包含所有列的临时表,则另一种解决方案是:

ALTER PROCEDURE sp_Member (
    @comcode INT = 0
  , @SubComCode INT = 0
  )
AS
BEGIN
  SET NOCOUNT ON

  SELECT  CONVERT(DECIMAL(18, 2), 0) TurnOver
        , *
  INTO    #result
  FROM    tbmember
  WHERE   can_flag = 'N'

  IF @comcode = '0'
  BEGIN
    UPDATE  r
    SET     TurnOver = (SELECT  SUM(amount)
                        FROM    tbcoudet
                        WHERE   memcode = r.memcode
                                AND expyear = (SELECT MAX(expyear)
                                               FROM   tbexpyear
                                              )
                                AND EXISTS ( SELECT itemcode
                                             FROM   tbitem
                                             WHERE  comcode = @comcode
                                                    AND SubComCode = @SubComCode
                                                    AND itemcode = tbcoudet.itemcode )
                        GROUP BY memcode
                              , expyear
                       )
    FROM    #result r
  END
  IF @SubComCode = '0'
  BEGIN
    UPDATE  r
    SET     TurnOver = (SELECT  SUM(amount)
                        FROM    tbcoudet
                        WHERE   memcode = r.memcode
                                AND expyear = (SELECT MAX(expyear)
                                               FROM   tbexpyear
                                              )
                                AND EXISTS ( SELECT itemcode
                                             FROM   tbitem
                                             WHERE  comcode = @comcode
                                                    AND itemcode = tbcoudet.itemcode )
                        GROUP BY memcode
                              , expyear
                       )
    FROM    #result r
  END

  SELECT TOP 10
          *
  FROM    #result
  WHERE   TurnOver IS NOT NULL
  ORDER BY TurnOver DESC
END

答案 5 :(得分:-2)

您正尝试在此过程中创建两次临时表。

在第二个查询中,请不要使用select ... into #result ...,而是使用insert into #result select ...,以便它不会再次尝试创建它。


请注意,前缀sp_表示系统过程,不应用于常规过程。