SQL Server - результаты одного оператора в транзакции сразу видны следующему? - PullRequest
2 голосов
/ 19 декабря 2011

Это:

use test;

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;


BEGIN TRANSACTION;

EXEC sp_RENAME 'table1.asd' , 'ads', 'COLUMN';

INSERT INTO table1 (ads) VALUES (12);

COMMIT

- простой пример, демонстрирующий, что я хотел бы сделать.

Я хочу каким-то образом изменить таблицу и выполнить вставки / удаления в одной транзакции(или другие изменения в таблице).

Проблема в том, что результаты из sp_RENAME никогда не видны сразу оператору INSERT.Я играл с разными уровнями изоляции транзакции - она ​​всегда одна и та же (поэтому транзакция никогда не фиксируется).

Обычно я просто использовал бы операторы GO, чтобы это было в отдельных пакетах, но мне нужно это в одном пакете, потому что ...

Моя настоящая задача - написать скрипт, который добавляет в таблицу идентификатор и FK (для этого требуется создать другую таблицу с новой схемой, выполнить вставку идентификатора из старой, переименовать таблицу иприменение ограничений).Мне нужно быть осторожным - если какая-то часть процедуры не удалась, я должен откатить всю транзакцию.Вот почему я хотел сделать что-то вроде этого:

BEGIN TRAN
    --some statement

    IF (@@ERROR <> 0) GOTO ERR_HANDLER

    -- some other statement

    IF (@@ERROR <> 0) GOTO ERR_HANDLER

COMMIT TRAN

RETURN 0

ERR_HANDLER:
PRINT 'Unexpected error occurred!'
ROLLBACK TRAN
RETURN 1

Поскольку ярлыки работают только внутри пакета, я не могу использовать операторы GO.

Так как я могу:

  • операторы make (т. Е. ALTER TABLE, sp_RENAME) имеют немедленный эффект?

или

  • написать целое решение другим способом, чтобы было безопасноработать в производственной БД?

1 Ответ

5 голосов
/ 19 декабря 2011

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

Вы можете поместить свои операторы, ссылающиеся на новое имя столбца, в блок EXEC(''), чтобы отложить компиляцию до тех пор, пока столбец не будет переименован.

EXEC sp_rename 'table1.asd' , 'ads', 'COLUMN';
EXEC('INSERT INTO table1 (ads) VALUES (12);')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...