В базе данных уже есть объект с именем #result - PullRequest
3 голосов
/ 15 декабря 2011
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 ]

9 голосов
/ 15 декабря 2011

Ошибка: временная таблица с таким именем уже существует - не создавайте ее заново, если она уже существует ....

Проблема заключается в том, как вы делаете выбор - выесть два места, где у вас есть

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 .......
    

Этот кодбудет работать, и вы сможете вставить два набора данных во временную таблицу.

4 голосов
/ 15 декабря 2011

Если вы не уверены, существует ли временная таблица или нет, но уверены, что до следующего оператора она вам не понадобится, используйте object_id function следующим образом:

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

Это не приведет к ошибке, если таблица не существует, и удалит ее, если она существует. По моему мнению, это хорошая практика для использования перед каждым:

select ... into #temp from ...
4 голосов
/ 15 декабря 2011

SELECT ... INTO ... всегда хочет создать новую временную таблицу.

Вместо этого создайте временную таблицу в верхней части процедуры (используя create table #result (columns)), а затем переписайте ваши выборки, используя вместо этого INSERT INTO (columns) SELECT ....

Я не могу выписать полный пример, так как не знаю определения ваших столбцов.

Даже если, конечно, только один из ваших if утверждений верен, синтаксический анализатор T-SQL довольно прост и все еще "видит" обе попытки объявления #result .


Кроме того, я не уверен, почему вы пишете свои if утверждения, подобные этому:

if @subcomcode='0'

Поскольку @subcomcode является целым числом, лучше не заключать в кавычки 0 литерал.

0 голосов
/ 22 марта 2017

У меня похожая проблема, но ни одно из предложенных здесь решений не помогает мне.У меня есть 6 if, аналогичных этим двум в хранимой процедуре, и это не позволит мне изменить процедуру, что не имеет смысла, это может сработать.Выдает ту же ошибку при изменении процедуры.Я должен иметь в #tbl в каждом if, потому что каждый 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
0 голосов
/ 01 ноября 2016

Договорились, что хорошо бросить, прежде чем создавать новые временные таблицы.Но простой обходной путь - просто закрыть соединение с БД при отладке такого рода вещей.Как отключение - вытирает все это для вас.

0 голосов
/ 15 декабря 2011

Вы пытаетесь создать временную таблицу дважды в процедуре.

Во втором запросе не используйте select ... into #result ..., а вместо insert into #result select ..., чтобы он не пытался создать его снова.


Обратите внимание, что префикс sp_ означает Системная процедура и не должен использоваться для обычных процедур.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...