ไม่อนุญาตให้ใช้คำสั่งแก้ไขฐานข้อมูลภายในธุรกรรมหลายข้อความ


13

ฉันได้ดาวน์โหลดตัวอย่างจากหน่วยความจำใน AdventureWorks จากที่นี่และทำตามขั้นตอนทั้งหมดที่อธิบายไว้ในเอกสารประกอบ อย่างไรก็ตามเมื่อฉันพยายามเรียกใช้สคริปต์ใน SQL Server Management Studio ฉันได้รับข้อความแสดงข้อผิดพลาด:

ไม่อนุญาตให้ใช้คำสั่งแก้ไขฐานข้อมูลภายในธุรกรรมหลายข้อความ

ข้อผิดพลาดชี้ไปที่บรรทัด 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

ไม่คุณไม่ได้ทำอะไรผิด ฉันได้สิ่งเดียวกัน ฉันแก้ไขมันโดยแบ่งตัวอย่างออกเป็นหลาย ๆ สคริปต์และเรียกใช้แต่ละส่วนของสคริปต์ตามลำดับในหน้าต่างแบบสอบถามของตัวเองแทนที่จะเป็นสคริปต์ตัวใหญ่ สิ่งนี้ทำงานได้ในกรณีของฉันเพราะฉันมักจะเรียกใช้ตัวอย่างเหล่านี้ใน VM แบบแยกตัว (ไม่ใช่บนเซิร์ฟเวอร์ที่ใช้งานจริง!) และการจัดการธุรกรรมไม่จำเป็นเนื่องจากฉันเป็นคนเดียวที่นี่

เมื่อดูที่สคริปต์อีกครั้งในวันนี้อย่างละเอียดยิ่งขึ้นไม่มีการจัดการธุรกรรมที่กำหนดไว้อย่างชัดเจน แต่บางทีคุณอาจวางสคริปต์ลงในหน้าต่างแบบสอบถามที่มีธุรกรรมที่ใช้งานอยู่หรือสร้างหน้าต่างแบบสอบถามใหม่ที่เพิ่มBEGIN TRANSACTION; / COMMIT TRANSACTION;คำสั่งโดยอัตโนมัติ

ฉันยังชี้ให้เห็น gotchas ที่มีศักยภาพอื่น ๆ สองสามในโพสต์บล็อกนี้


1
"บางทีคุณวางสคริปต์ลงในหน้าต่างแบบสอบถามที่มีธุรกรรมที่ใช้งานอยู่" ซึ่งดูเหมือนว่าจะมีปัญหาเพราะเมื่อฉันเรียกใช้แบบสอบถามทั้งหมดในหน้าต่างใหม่มันทำงานได้
Petter Brodin

9

ฉันเห็นด้วยกับ @AaronBertrand คุณไม่ได้ทำอะไรผิด นี่จะไม่ใช่ครั้งแรกที่ฉันได้เห็นสคริปต์ของ Microsoft พร้อมจุดบกพร่อง ด้วยสคริปต์ที่สมจริงมากเท่าที่พวกเขาเผยแพร่ฉันจะแปลกใจที่จะไม่เห็นมัน

โดยเฉพาะปัญหาคือALTER DATABASEไม่อนุญาตให้ทำธุรกรรมใด ๆ คุณสามารถดูการอ้างอิง BOL ได้ที่นี่: คำสั่งTransact-SQL ที่อนุญาตในธุรกรรม

ในความเป็นจริงแม้แต่สคริปต์ง่าย ๆ เช่นนี้ล้มเหลวด้วยข้อผิดพลาดเดียวกัน

BEGIN TRANSACTION
ALTER DATABASE AdventureWorks2012 SET READ_WRITE
COMMIT

อย่างที่แอรอนบอกเอาการจัดการการทำธุรกรรม (หรืออย่างน้อยALTER DATABASEคำสั่งจากการทำธุรกรรม) และคุณควรจะดี


-2

ใช้ "ไป" เพื่อแยกการทำธุรกรรม ที่จะแก้ปัญหา (มันง่ายกว่าเรียกใช้ทีละหนึ่ง) นอกจากนี้ยังสามารถเปลี่ยนระดับการแยก (ไม่ผ่านการทดสอบ)

SET TRANSACTION ISOLATION LEVEL SERIALISABLE

Begin tran

---Statements goes here

commit tran

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

คุณอาจต้องการทดสอบรหัสของคุณก่อนโพสต์เมื่อผู้อื่นได้ระบุว่าALTER DATABASEไม่สามารถดำเนินการภายในการทำธุรกรรม การตั้งค่าระดับการแยกให้SERIALIZABLEไม่มีผลกับสิ่งนี้
Max Vernon

"GO" ไม่ใช่คำสั่ง SQL เป็นคำสั่งให้ SSMS ส่งคำสั่งล่วงหน้าไปยัง SQL Server เป็นชุด คุณสามารถเปลี่ยนแปลงสิ่งนี้ได้หากคุณกล้า: เครื่องมือ -> ตัวเลือก -> การดำเนินการสืบค้น -> SQL Server หลายชุดสามารถส่งภายในธุรกรรมเดียว
Michael Green
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.