Вставка SQL в временную таблицу без указания значений?

У меня есть хранимая процедура, которая в настоящее время использует один CTE. Этот работает так:

WITH MY_CTE AS
(
    // Logic here uses SELECT * from a single table.
)
SELECT *
INTO #Tasks
FROM MY_CTE;

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

IF @Option = 1
    BEGIN
        INSERT INTO #Tasks
        (
            WITH MY_OTHER_CTE
            (
                // Logic here uses SELECT * from same table as first CTE.
            )
            SELECT *
            FROM MY_OTHER_CTE
        )
    END

Проблема в том, что вызов INSERT INTO #Tasks требует указания столбцов VALUES. Оба CTE возвращают записи из одной и той же таблицы. Хорошим преимуществом исходной хранимой процедуры было то, что она работала, даже если столбцы в этой таблице изменились, поскольку я использовал SELECT *. Я мог указать столбцы, зная, что они представляют собой в общей таблице, но я теряю это преимущество (которое в данном конкретном случае является чрезвычайно полезным преимуществом). Есть ли способ выполнить то, что я пытаюсь сделать, зная, что они оба выбирают из одной и той же таблицы и что столбцы всегда будут совпадать?


person Ocelot20    schedule 13.05.2011    source источник


Ответы (2)


Это работает?

;WITH MY_OTHER_CTE AS
(
    // Logic here uses SELECT * from same table as first CTE.
)
INSERT INTO #Tasks
    SELECT *
    FROM MY_OTHER_CTE

У вас может возникнуть еще одна проблема, если таблица, из которой вы выбираете (и, следовательно, временная таблица), имеет столбец идентификаторов.

person Michael J Swart    schedule 13.05.2011
comment
Отлично, это работает. Я думаю, у меня просто не было правильного синтаксиса. Не могли бы вы уточнить потенциальные проблемы с колонкой идентификаторов? В таблице есть столбец идентификаторов, но он все еще работает нормально. Второй CTE не может вставлять дубликаты из первого, поэтому был ли это единственный источник беспокойства? Спасибо. - person Ocelot20; 13.05.2011
comment
Мой собственный тест дал мне эту ошибку со столбцом идентификаторов: явное значение для столбца идентификаторов в таблице «#Tasks» может быть указано только тогда, когда используется список столбцов и IDENTITY_INSERT включен. Так что тестируйте, тестируйте, тестируйте, удачи. - person Michael J Swart; 13.05.2011

Я начну с обязательного «перечислять столбцы — это хорошая практика по 6 354 причинам». Но мы все были там, где нельзя ;-)

В любом случае, я бы решил это с помощью производных таблиц и союзов. Ключевым моментом здесь является выполнение серии UNION и использование ваших критериев WHERE для исключения запросов, которые вы не хотите запускать. Очевидно, что все таблицы должны иметь одинаковые типы данных в одном и том же порядке, чтобы это работало, но код может выглядеть примерно так....

WITH MY_CTE AS (

    SELECT *
    FROM (
        SELECT  * 
        FROM    FirstTable
        WHERE   <your criteria here>

            UNION 

        SELECT  *
        FROM    FirstTable_OR_SomeOtherTable
        WHERE   <your criteria>
            AND @Option1 = 1

            UNION 

        SELECT *
        FROM    OnAndOnAndSoOn
        WHERE   <your criteria>
            AND @Option2 = 1

    ) AS MyDerivedTable   
)
SELECT *
INTO #Tasks
FROM MY_CTE;

РЕДАКТИРОВАТЬ

Думаю, я проигнорировал ваш запрос «два CTE», но я подозреваю, что это приведет вас к тому же месту.

person EBarr    schedule 13.05.2011