2013-08-12 3 views
1

Выполнения код ниже:заявление Alter в транзакции

use AdventureWorks2008R2 
begin transaction 
BEGIN 
alter table HumanResources.Department add newcolumn int 
update HumanResources.Department set newcolumn=1 where departmentid=1 
END 
commit 

Ошибки я получаю:

Неверное имя столбца 'newcolumn'.

Могут ли ALTER заявления быть включены в Сделки следующим образом? Если да, то как я могу предотвратить эту ошибку?

Я исследовал этот онлайн e.g. here. Я не нашел ответа на свой конкретный вопрос.

+0

Да, вы можете. Это легко проверить. –

+0

@ Гамлет Я думаю, что вы, возможно, пропустили точку вопроса. –

ответ

7

Да, вы можете включить ALTER в сделку. Проблема в том, что синтаксический анализатор синтаксиса для вашего оператора UPDATE и не может «видеть», что вы также выполняете ALTER. Один из способов заключается в использовании динамического SQL, так что анализатор не проверяет синтаксис (и не проверить имена столбцов) до выполнения, где ALTER будет уже произошло:

BEGIN TRANSACTION; 

    ALTER TABLE HumanResources.Department ADD newcolumn INT; 

    EXEC sp_executesql N'UPDATE HumanResources.Department 
    SET newcolumn = 1 WHERE DepartmentID = 1;'; 

COMMIT TRANSACTION; 

Обратите внимание, что отступы делает блоки кода гораздо больше легко идентифицировать (и ваш BEGIN/END был лишним).

+0

Можно ли отключить проверку парсера? Наверное, нет. – w0051977

+0

Нет, и как часто вы добавляете столбцы в таблицу, где это будет проблемой? Вышеприведенный код можно было запустить только один раз, например. Поэтому использование динамического SQL для ALTER также может сделать это немного более правдоподобным. –

+0

Я согласен с тем, что вы сделали +1. Проблема в том, что я уже написал скрипт и должен будет изменить каждый оператор SQL. Существуют ли какие-либо ограничения для создания двух транзакций: один для операторов ALTER и один для UPDATES/INSERTS. Первая транзакция (ALTERS) будет передана до начала транзакции. – w0051977

0

Если вы проверяете наличие столбца, тогда он должен работать.

BEGIN TRANSACTION; 

    IF COL_LENGTH('table_name', 'newcolumn') IS NULL 
    BEGIN 
     ALTER TABLE table_name ADD newcolumn INT; 
    END 

    EXEC sp_executesql N'UPDATE table_name 
    SET newcolumn = 1 WHERE DepartmentID = 1;'; 

COMMIT TRANSACTION; 
+0

«ALTER» - это не та часть, которая терпит неудачу. –

+0

Извините, но почему 'UPDATE' терпит неудачу, если' ALTER' работает? – AgentSQL

+1

Поскольку, если вы не ставите 'UPDATE' в динамический SQL, SQL Server пытается проанализировать имя столбца, указанное в' UPDATE', прежде чем он когда-либо попытается изменить столбец. Вы взяли код из моего ответа; Разве вы тоже его не читали? –

0

Аарон уже все объяснил. Другой альтернативой, которая работает для специальных сценариев в SSMS, является вставка разделителя пакетов GO, так что сценарий отправляется как две части на сервер. Это работает только в том случае, если это действительно так, чтобы разделить скрипт в первую очередь (вы не можете разделить тело IF).

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