SQL Server 2000: недопустимое имя столбца 'bar'

Думаю, я только что обнаружил странную ошибку в SQL Server 2000.

Следующий запрос возвращает ошибку

Сообщение 207, уровень 16, состояние 3, строка 7
Недопустимое имя столбца "bar"

Если я выполню тот же самый запрос в SQL Server 2005, он будет работать. Это также работает, если я select #weirdness.*. Есть ли какое-то обходное решение, которое можно использовать в процедуре? Я знаю, что go помогает, но его нельзя использовать в процедуре. Кстати, мы собираемся избавиться от SQL Server 2000, но это требует времени.

select 1 as  foo
into #weirdness;

alter table #weirdness add bar int identity;

--select  #weirdness.*    --works
select #weirdness.bar  --fails
from #weirdness;

Система:

Microsoft SQL Server 2000 - 8.00.2066 (Intel X86) 11 мая 2012 г. 18:41:14
Copyright (c) 1988-2003 гг. Microsoft Corporation Standard Edition для Windows NT 5.2 (сборка 3790: пакет обновления 2)


person jumxozizi    schedule 22.09.2016    source источник


Ответы (2)


Вот обходные пути, которые я мог придумать на данный момент.

По возможности используйте SQL Server 2005 или новее.

Если возможно, разделите сценарий на несколько пакетов (невозможно в процедуре):

select  1   as  foo
into    #weirdness;

alter table #weirdness add bar int identity;

go  --split into multiple batches

--select  #weirdness.*    --works
select  #weirdness.bar  --fails
from    #weirdness;

Сначала создайте таблицу:

create table #weirdness (
    foo bit
,   bar int identity
);

insert into #weirdness(foo)
select  1   as  foo;

select  #weirdness.bar
from    #weirdness;
person jumxozizi    schedule 22.09.2016

Это не ошибка, это задокументированное поведение. Примерьте это на размер:

select 1 as foo into #weirdness;
go
alter table #weirdness add bar int;
select #weirdness.bar
from #weirdness;

Вы увидите, что это не удается и в SQL Server 2005, жалуясь на то, что «полосы» не существует.

Почему не получается? Поскольку, согласно документации, вам не разрешено делать это:

Невозможно изменить таблицу, а затем новые столбцы, указанные в том же пакете.

Так почему же создание и изменение таблицы с последующим обращением к ней все же работает, если мы делаем это одним пакетом в SQL Server 2005, но не в SQL Server 2000? Это связано с перекомпиляцией операторов, которая также задокументирована выше и появилась впервые в 2005 году.

В SQL Server 2005, поскольку #weirdness не существует в начале пакета, SQL Server не компилирует операторы, ссылающиеся на него. select .. into выполняется, и все операторы, ссылающиеся на него, помечаются для перекомпиляции. Затем эти операторы компилируются и выполняются один за другим. К тому времени, когда мы ссылаемся на #weirdness.bar, он был создан и компиляция прошла успешно.

В SQL Server 2000, поскольку #weirdness не существует в начале пакета, SQL Server не компилирует операторы, ссылающиеся на него. Выполняется select .. into, и весь пакет помечается для перекомпиляции. Но компиляция select #weirdness.bar завершается неудачно, поскольку alter table не был выполнен, и пакет останавливается.

Таким образом, документация должна на самом деле читать: «таблица не может быть изменена, а затем новые столбцы, указанные в том же пакете, если только таблица не существует вообще при запуске пакета, тогда вы можете уйти с этим материалом из SQL Server 2005. и далее, но полагаться на это, наверное, не такая уж и горячая идея ". Вы можете понять, почему они сделали это проще.

person Jeroen Mostert    schedule 23.09.2016