Instruction ALTER DATABASE non autorisée dans une transaction à instructions multiples

13

J'ai téléchargé l'exemple en mémoire basé sur AdventureWorks à partir d' ici et j'ai suivi toutes les étapes décrites dans le document d'accompagnement. Cependant, lorsque j'essaie d'exécuter le script dans SQL Server Management Studio, j'obtiens le message d'erreur:

Instruction ALTER DATABASE non autorisée dans une transaction à instructions multiples

L'erreur pointe vers la ligne 9, qui est:

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

Comme il s'agit (plus ou moins) de documentation officielle de Microsoft, je suppose que c'est quelque chose que je fais mal, mais je ne peux pas comprendre ce que c'est.

Petter Brodin
la source

Réponses:

13

Non, tu ne fais rien de mal. J'ai eu la même chose. Je l'ai résolu en divisant l'échantillon en plusieurs scripts et en exécutant chaque section du script séquentiellement, dans sa propre fenêtre de requête, au lieu d'un seul gros script. Cela a fonctionné dans mon cas car j'exécute toujours ces exemples sur une machine virtuelle isolée (pas sur un serveur de production!) Et la gestion des transactions n'est pas nécessaire car je suis le seul ici.

En examinant à nouveau le script aujourd'hui de plus près, aucune gestion de transaction n'est définie explicitement, mais vous avez peut-être collé le script dans une fenêtre de requête qui avait déjà une transaction active ou créé une nouvelle fenêtre de requête qui a automatiquement ajouté des BEGIN TRANSACTION; / COMMIT TRANSACTION;instructions.

J'ai également souligné quelques autres problèmes potentiels dans cet article de blog .

Aaron Bertrand
la source
1
"peut-être que vous avez collé le script dans une fenêtre de requête qui avait déjà une transaction active" Cela semble avoir été le problème, car lorsque j'ai exécuté toute la requête dans une nouvelle fenêtre, cela a fonctionné.
Petter Brodin
9

Je suis d'accord avec @AaronBertrand que vous ne faites rien de mal. Ce ne serait pas la première fois que je verrais un script Microsoft contenant un bogue. De façon réaliste avec autant de scripts qu'ils publient, je serais surpris de n'en voir aucun.

Plus précisément, le problème est que ce ALTER DATABASEn'est pas autorisé du tout dans une transaction. Vous pouvez voir la référence BOL ici: Instructions Transact-SQL autorisées dans les transactions

En fait, même un script aussi simple que celui-ci échoue avec la même erreur.

BEGIN TRANSACTION
ALTER DATABASE AdventureWorks2012 SET READ_WRITE
COMMIT

Comme l'a dit Aaron, supprimez la gestion des transactions (ou du moins la ALTER DATABASEdéclaration de la transaction) et ça devrait aller.

Kenneth Fisher
la source
-2

Utilisez "Aller" pour séparer les transactions. Cela résoudra le problème. (C'est facile à exécuter un par un.) Peut également modifier le niveau d'isolement (non testé)

SET TRANSACTION ISOLATION LEVEL SERIALISABLE

Begin tran

---Statements goes here

commit tran

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
Eranga Priyakara
la source
Vous voudrez peut-être tester votre code avant de le publier lorsque d'autres personnes ont déjà identifié que ALTER DATABASEcela ne peut pas être effectué dans une transaction. La définition du niveau d'isolement SERIALIZABLEn'a aucun effet sur cela.
Max Vernon
"GO" n'est pas une instruction SQL. Il s'agit d'une instruction à SSMS de soumettre les instructions précédentes à SQL Server en tant que lot. Vous pouvez changer cela si vous vous sentez courageux: Outils -> Options -> Exécution de requête -> SQL Server. De nombreux lots peuvent être soumis en une seule transaction.
Michael Green