Instrukcja ALTER DATABASE jest niedozwolona w przypadku transakcji z wieloma wyciągami

13

Pobrałem stąd próbkę w pamięci opartą na AdventureWorks i wykonałem wszystkie kroki opisane w dołączonym dokumencie. Jednak gdy próbuję uruchomić skrypt w SQL Server Management Studio, pojawia się komunikat o błędzie:

Instrukcja ALTER DATABASE jest niedozwolona w przypadku transakcji z wieloma wyciągami

Błąd wskazuje na linię 9, która jest:

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

Ponieważ jest to (mniej więcej) oficjalna dokumentacja Microsoft, zakładam, że robię coś źle, ale nie mogę zrozumieć, co to jest.

Petter Brodin
źródło

Odpowiedzi:

13

Nie, nie robisz nic złego. Mam to samo. Rozwiązałem go, dzieląc próbkę na wiele skryptów i uruchamiając każdą sekcję skryptu sekwencyjnie, we własnym oknie zapytania, zamiast jako jeden duży skrypt. To zadziałało w moim przypadku, ponieważ zawsze uruchamiam te próbki na odizolowanej maszynie wirtualnej (nie na serwerze produkcyjnym!), A obsługa transakcji jest niepotrzebna, ponieważ jestem tu jedyną osobą.

Przy bliższym spojrzeniu na skrypt dzisiaj nie ma jawnie zdefiniowanej obsługi transakcji, ale być może wkleiłeś skrypt w oknie zapytania, które już miało aktywną transakcję, lub utworzyłeś nowe okno zapytania, które automatycznie dodawało BEGIN TRANSACTION; / COMMIT TRANSACTION;instrukcje.

W tym wpisie na blogu wskazałem także kilka innych potencjalnych problemów .

Aaron Bertrand
źródło
1
„być może wkleiłeś skrypt w oknie zapytania, które już miało aktywną transakcję” To wydaje się stanowić problem, ponieważ kiedy uruchomiłem całe zapytanie w nowym oknie, zadziałało.
Petter Brodin
9

Zgadzam się z @AaronBertrand, że nie robisz nic złego. To nie byłby pierwszy raz, gdy widziałem skrypt Microsoft z błędem. Realistycznie przy tylu publikowanych skryptach zdziwiłbym się, że ich nie widziałem.

W szczególności problem polega na tym, że w ALTER DATABASEogóle nie jest dozwolony w transakcji. Odwołanie do BOL można zobaczyć tutaj: Transact-SQL Instrukcje dozwolone w transakcjach

W rzeczywistości nawet tak prosty skrypt, jak ten, zawiedzie z tym samym błędem.

BEGIN TRANSACTION
ALTER DATABASE AdventureWorks2012 SET READ_WRITE
COMMIT

Jak powiedział Aaron, usuń obsługę transakcji (lub przynajmniej ALTER DATABASEwyciąg z transakcji) i powinieneś być w porządku.

Kenneth Fisher
źródło
-2

Użyj „Idź”, aby rozdzielić transakcje. To rozwiąże problem. (Jest to łatwe niż uruchamianie jeden po drugim.) Można również zmienić poziom izolacji (nie testowano)

SET TRANSACTION ISOLATION LEVEL SERIALISABLE

Begin tran

---Statements goes here

commit tran

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
Eranga Priyakara
źródło
Możesz przetestować swój kod przed opublikowaniem, gdy inni już stwierdzili, że ALTER DATABASEnie można go wykonać w ramach transakcji. Ustawienie poziomu izolacji na SERIALIZABLEnie ma na to wpływu.
Max Vernon
„GO” nie jest instrukcją SQL. Jest to instrukcja dla SSMS, aby przesłać poprzednie instrukcje do programu SQL Server jako partia. Możesz to zmienić, jeśli czujesz się odważny: Narzędzia -> Opcje -> Wykonanie zapytania -> SQL Server. Wiele partii można przesłać w ramach jednej transakcji.
Michael Green