La instrucción ALTER DATABASE no está permitida dentro de la transacción de varios estados

13

He descargado el ejemplo en memoria basado en AdventureWorks de aquí , y seguí todos los pasos descritos en el documento adjunto. Sin embargo, cuando intento ejecutar el script en SQL Server Management Studio, aparece el mensaje de error:

La instrucción ALTER DATABASE no está permitida dentro de la transacción de varios estados

El error apunta a la línea 9, que es:

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

Dado que esta es (más o menos) documentación oficial de Microsoft, supongo que es algo que estoy haciendo mal, pero no puedo entender qué es.

Petter Brodin
fuente

Respuestas:

13

No, no estás haciendo nada malo. Yo tengo la misma cosa. Lo resolví dividiendo la muestra en varios scripts y ejecutando cada sección del script secuencialmente, en su propia ventana de consulta, en lugar de como un gran script. Esto funcionó en mi caso porque siempre estoy ejecutando estas muestras en una VM aislada (¡no en un servidor de producción!) Y el manejo de transacciones es innecesario ya que soy el único aquí.

Mirando el guión nuevamente más de cerca hoy, no hay un manejo de transacciones definido explícitamente, pero quizás pegó el guión en una ventana de consulta que ya tenía una transacción activa, o creó una nueva ventana de consulta que agregó BEGIN TRANSACTION; / COMMIT TRANSACTION;declaraciones automáticamente .

También señalé un par de otras posibles trampas en esta publicación de blog .

Aaron Bertrand
fuente
1
"quizás pegó el script en una ventana de consulta que ya tenía una transacción activa" Ese parece haber sido el problema, porque cuando ejecuté toda la consulta en una nueva ventana, funcionó.
Petter Brodin
9

Estoy de acuerdo con @AaronBertrand, no estás haciendo nada malo. Esta no sería la primera vez que veo un script de Microsoft con un error. Siendo realistas con tantos scripts como publican, me sorprendería no ver ninguno.

Específicamente, el problema es que ALTER DATABASEno está permitido en ninguna transacción. Puede ver la referencia de BOL aquí: Declaraciones de Transact-SQL permitidas en transacciones

De hecho, incluso un script tan simple como este falla con el mismo error.

BEGIN TRANSACTION
ALTER DATABASE AdventureWorks2012 SET READ_WRITE
COMMIT

Como dijo Aaron, elimine el manejo de la transacción (o al menos la ALTER DATABASEdeclaración de la transacción) y debería estar bien.

Kenneth Fisher
fuente
-2

Use "Ir" para separar las transacciones. Eso resolverá el problema. (Es fácil de ejecutar uno por uno). También puede cambiar el nivel de aislamiento (no probado)

SET TRANSACTION ISOLATION LEVEL SERIALISABLE

Begin tran

---Statements goes here

commit tran

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
Eranga Priyakara
fuente
Es posible que desee probar su código antes de publicarlo cuando otros ya hayan identificado que ALTER DATABASEno se puede realizar dentro de una transacción. Establecer el nivel de aislamiento en SERIALIZABLEno tiene ningún efecto sobre esto.
Max Vernon
"IR" no es una declaración SQL. Es una instrucción para SSMS enviar las declaraciones anteriores a SQL Server como un lote. Puede cambiar esto si se siente valiente: Herramientas -> Opciones -> Ejecución de consulta -> SQL Server. Se pueden enviar muchos lotes dentro de una sola transacción.
Michael Green