Почему SQL Server считает, что временная таблица уже существует, а ее нет? - PullRequest
7 голосов
/ 28 января 2011

Справочная информация: есть хранимая процедура, которая «заполняет» временную таблицу с заданным именем. Процедура является общей в том смысле, что она проверяет схему временной таблицы, а затем выполняет различные «вещи» в зависимости от схемы. Я понимаю, что это немного странно, но я не хочу менять это, потому что в большинстве ситуаций все работает нормально, кроме ....

Если у меня есть хранимая процедура, которая создает две разные схемы для временной таблицы с тем же именем. Логически он создает только одну временную таблицу в зависимости от того, какая ветвь IF. Проблема в том, что когда Sproc проверяется SQL Server, кажется, что он оценивает обе стороны IF (что имеет смысл, если он проверяет синтаксис SQL).

Итак, этот SQL не работает:

IF (1=1)
BEGIN
    CREATE TABLE #test
    (
        a BIGINT NOT NULL,
        b BIGINT NOT NULL
    )
END 
ELSE
BEGIN
    CREATE TABLE #test
    (
        a BIGINT NOT NULL,
        b BIGINT NOT NULL,
        c BIGINT NOT NULL   
    )   
END

--exec SomeProcedureWhichDoesStuffWith#Test

DROP TABLE #test 

со следующей ошибкой:

Сообщение 2714, Уровень 16, Состояние 1, Строка 14
Уже есть объект с именем '#test' в базе данных.

Кажется, что никакая комбинация отбрасываемой таблицы внутри ifs (до или после создания таблицы DDL) не удовлетворяет контролеру sql.

Есть идеи, как я могу это сделать? Могу ли я, например, сказать SQL не выполнять проверку синтаксиса и просто принять sproc как есть?

Ответы [ 4 ]

7 голосов
/ 28 января 2011

Это ограничение.Динамический SQL также не будет работать, так как #tmp будет создан в новом сеансе и немедленно потерян.Для приведенного фрагмента EXACT, как показано, это действует так же

CREATE TABLE #test
(
    a BIGINT NOT NULL,
    b BIGINT NOT NULL
)

IF not (1=1)
    ALTER TABLE #test ADD c BIGINT NOT NULL   

В одном пакете не может быть двух CREATE .. #name, но это также будет работать в общем виде

IF (1=1)
BEGIN
    CREATE TABLE #test
    (
        a BIGINT NOT NULL,
        b BIGINT NOT NULL
    );
END 
GO

IF NOT (1=1)
BEGIN
    CREATE TABLE #test
    (
        a BIGINT NOT NULL,
        b BIGINT NOT NULL,
        c BIGINT NOT NULL   
    )
END
2 голосов
/ 11 марта 2014

Вместо #test используйте полное имя. Например,

[tempdb].[dbo].[temptable]

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

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

Когда закончите с этим, обязательно бросьте его:

DROP TABLE [tempdb].[dbo].[temptable]
0 голосов
/ 09 февраля 2011

Вы всегда можете "обмануть":

DECLARE @SQL VARCHAR(200)

IF (1=1)
BEGIN
    SET @SQL = 'CREATE TABLE #Temp     ' +
               '(                      ' +
               '    a BIGINT NOT NULL, ' +
               '    b BIGINT NOT NULL  ' +
               ')                      '
END
ELSE
BEGIN
    SET @SQL = 'CREATE TABLE #Temp     ' +
               '(                      ' +
               '    a BIGINT NOT NULL, ' +
               '    b BIGINT NOT NULL, ' +
               '    c BIGINT NOT NULL  ' +
               ')                      '
END

EXEC SP_EXECUTESQL @SQL
0 голосов
/ 28 января 2011

так как у меня нет sql 2008, я не могу это проверить. однако, насколько я знаю, это проблема синтаксического анализатора явно с временными таблицами. то же самое будет нормально работать с обычными таблицами

чтобы разобраться, просто разделите ваш код с помощью логических операторов GO

в идеале: проверьте наличие временных таблиц перед созданием временных таблиц, удалите их, если они существуют, запустите go, снова создайте временные таблицы, запустите go, затем любую постобработку, запустите go, наконец бросьте их снова и выстрелите в последний раз


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

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