Оператор ALTER DATABASE не разрешен в транзакции с несколькими операторами

13

Отсюда я скачал образец In-memory на основе AdventureWorks и выполнил все шаги, описанные в прилагаемом документе. Однако, когда я пытаюсь запустить сценарий в SQL Server Management Studio, я получаю сообщение об ошибке:

Оператор ALTER DATABASE не разрешен в транзакции с несколькими операторами

Ошибка указывает на строку 9, которая:

IF NOT EXISTS (SELECT * FROM sys.data_spaces WHERE type='FX')
    ALTER DATABASE CURRENT ADD FILEGROUP [AdventureWorks2012_mod] 
    CONTAINS MEMORY_OPTIMIZED_DATA
GO

Поскольку это (более или менее) официальная документация Microsoft, я предполагаю, что я что-то не так делаю, но я не могу понять, что это такое.

Петер Бродин
источник

Ответы:

13

Нет, ты не делаешь ничего плохого. Я получил то же самое. Я решил эту проблему, разбив образец на несколько сценариев и выполняя каждый раздел сценария последовательно, в своем собственном окне запроса, а не как один большой сценарий. В моем случае это работало, потому что я всегда запускаю эти образцы в изолированной виртуальной машине (не на производственном сервере!), И обработка транзакций не требуется, поскольку я здесь единственный.

Сегодня, если присмотреться к сценарию еще раз, нет более явной обработки транзакций, но, возможно, вы вставили сценарий в окно запроса, в котором уже была активная транзакция, или создали новое окно запроса, в котором автоматически добавляются BEGIN TRANSACTION; / COMMIT TRANSACTION;операторы.

Я также указал на несколько других потенциальных ошибок в этом блоге .

Аарон Бертран
источник
1
«Возможно, вы вставили скрипт в окно запроса, в котором уже была активная транзакция». Это, похоже, проблема, потому что когда я запускал весь запрос в новом окне, он работал.
Петер Бродин
9

Я согласен с @AaronBertrand, что вы не делаете ничего плохого. Это был бы не первый раз, когда я видел скрипт Microsoft с ошибкой в ​​нем. Реально с таким количеством сценариев, которые они публикуют, я был бы удивлен, не увидев ни одного.

В частности, проблема в том, что ALTER DATABASEв транзакции вообще не допускается. Вы можете увидеть ссылку на BOL здесь: заявления Transact-SQL, разрешенные в транзакциях

На самом деле, даже такой простой скрипт, как этот, завершается с той же ошибкой.

BEGIN TRANSACTION
ALTER DATABASE AdventureWorks2012 SET READ_WRITE
COMMIT

Как сказал Аарон, удалите обработку транзакции (или, по крайней мере, ALTER DATABASEоператор из транзакции), и все будет в порядке.

Кеннет Фишер
источник
-2

Используйте «Go» для разделения транзакций. Это решит проблему. (Это проще, чем запускать по одному.) Также можно изменить уровень изоляции (не проверено)

SET TRANSACTION ISOLATION LEVEL SERIALISABLE

Begin tran

---Statements goes here

commit tran

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
Эранга Приякара
источник
Вы можете проверить свой код перед публикацией, когда другие уже определили, что ALTER DATABASEне может быть выполнено в транзакции. Установка уровня изоляции на SERIALIZABLEэто никак не влияет.
Макс Вернон
«GO» не является оператором SQL. Это инструкция для SSMS, чтобы отправить предыдущий оператор (ы) на SQL Server в виде пакета. Вы можете изменить это, если чувствуете смелость: Инструменты -> Параметры -> Выполнение запроса -> SQL Server. Многие партии могут быть отправлены в рамках одной транзакции.
Майкл Грин