2011-12-15 2 views
2
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 [email protected] and 
        [email protected] 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 [email protected] 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-код, и когда я собираюсь выполнить процедуру магазина, то я получаю ошибкуСуществует уже объект с именем «#RESULT» в базе данных

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

Может кто-нибудь сказать мне, что проблема в?

+1

Добро пожаловать в StackOverflow: если вы разместите код, XML или данных образцов, пожалуйста ** ** выделить те строки в текстовом редакторе и нажмите кнопку «образцы кода» ('{}') на панели инструментов редактора, чтобы красиво отформатировать и выделить синтаксис! –

+0

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

+0

@ user1099310, используйте кнопку панели инструментов '{}' для представления частей вашего кода. –

ответ

2

SELECT ... INTO ... всегда хочет создать temp table.

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

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

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


Как и в сторону, я не знаю, почему вы пишете ваши if заявления, как это:

if @subcomcode='0' 

Поскольку @subcomcode является ИНТ, вы бы лучше не цитируя 0 буквальный.

+0

Да, для «... парсера довольно простая часть», потому что даже если вы последовательно снижаетесь, создаете, удаляете, создаете, эта ошибка все равно возникает в 2012 году. – crokusek

8

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

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

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

... и не забудьте 'DROP TABLE # result' в конце! – onedaywhen

+0

@oneday когда: temp-таблицы, такие как '# result', автоматически отбрасываются при завершении сеанса/соединения (или если вы создаете их внутри хранимой процедуры - при завершении хранимой процедуры). Поэтому, если вы используете принцип «открыть как можно ближе/близко сразу после использования», как разговаривать с SQL Server, когда вы закрываете соединение, любые локальные таблицы temp, назначенные вашему сеансу, автоматически отбрасываются –

+3

Мне нравится делать намерение ясно. Также удобно, когда копировать + вставлять содержимое proc в новое окно запроса для тестирования и т. Д. Нет, biggie, конечно;) – onedaywhen

-2

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

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


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

+0

temp-таблицы автоматически отбрасываются в конце хранимых процедур, которые их создают. –

+0

Уверены ли вы в этом? Я использую временные таблицы для всех процедур. – Guffa

+1

См. Раздел [Временные таблицы] (http://msdn.microsoft.com/en-us/library/ms174979.aspx), первая маркерная точка «Локальная временная таблица, созданная в хранимой процедуре, автоматически отбрасывается, когда хранимая процедура закончен." Вы можете использовать временные таблицы для процедур, но вы должны * создавать * эти таблицы во внешней области. –

4

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

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

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

select ... into #temp from ... 
0

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

0

У меня есть аналогичная проблема, но ни одно предлагаемое решение здесь не помогает. У меня есть 6, похожее на два в хранимой процедуре, и это не позволит мне изменить процедуру, которая не имеет смысла, она явно может работать. Выдает такую ​​же ошибку при изменении процедуры. Я должен иметь в #tbl в каждом случае, потому что каждый, если имеет выбор с разными столбцами, и я не хочу делать таблицу для каждого выбора. Другой вариант динамических выбирает ...

Я должен был сделать это динамический (не все), как это:

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

Добро пожаловать в SO! Поскольку это не ответ, а новый вопрос, пожалуйста, найдите существующие вопросы и ответы, а затем, если вы не можете найти решение, создайте новый вопрос. –

Смежные вопросы