ฉันจะจัดการกับข้อ จำกัด FK เมื่อนำเข้าข้อมูลโดยใช้ตัวช่วยสร้างการนำเข้า / ส่งออก DTS ได้อย่างไร


16

ฉันพยายามใช้ตัวช่วยสร้างการนำเข้าและส่งออกเซิร์ฟเวอร์ SQL เพื่อคัดลอกข้อมูลจากฐานข้อมูลการผลิตของฉันไปยังฐานข้อมูล dev ของฉัน แต่เมื่อฉันทำมันล้มเหลวด้วยข้อผิดพลาด "การแทรก INSERT ขัดกับข้อ จำกัด ของต่างประเทศ" ฉันมีตารางมากกว่า 40 ตาราง ของข้อ จำกัด FK มีวิธีง่าย ๆ ในการจัดการกับสิ่งนี้โดยไม่ต้องเขียนข้อ จำกัด แบบหล่น / เพิ่มสคริปต์ constrat?

แก้ไข: ฉันเพิ่งพบว่าในรุ่นของ SQL Server ซึ่งเป็นสิ่งที่ฉันกำลังทำงานอยู่ DTS จะไม่อนุญาตให้คุณบันทึกแพ็คเกจ

คำตอบ:


28

ฉันได้รับโซลูชันนี้ที่ SQLTeam.com:

ใช้:

 EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

จากนั้นนำเข้าข้อมูลของคุณ

EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT all'

ใช้วิธีการนั้นฉันสามารถนำเข้าข้อมูลทั้งหมดโดยไม่มีปัญหา


1
sp_msforeachtable(และsp_MSForEachDb) ไม่มีเอกสารและไม่สนับสนุน คุณไม่ควร / หลีกเลี่ยงการใช้มัน มันอาจข้ามตาราง !! ดูโพสต์นี้จาก @AaronBertrand -> sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/…และรายการเชื่อมต่อนี้ - (MS ระบุว่าพวกเขาจะไม่แก้ไข) -> connect.microsoft.com/SQLServer / feedback / details / 264677 / …
Kin Shah

ทำงานอย่างสมบูรณ์แบบสำหรับฉันหลังจากชั่วโมงของการตีสมองของฉันพยายามที่จะหลีกเลี่ยงข้อ จำกัด FK สำหรับการส่งออกข้อมูล
levininja

ทำงานบน Azure SQL V12 ฉันได้รับข้อผิดพลาด "ไม่พบกระบวนงานที่เก็บไว้ 'sp_msforeachtable'"
Dai

ไม่ทำงานเลย: /
Douglas Gaskell

คุณเป็นคนช่วยชีวิต
Can ŞahinBakır

5

ฉันผลิตสำเนาฐานข้อมูลบนเครื่องของฉันจากเซิร์ฟเวอร์ที่ฉันไม่ได้ควบคุม

ฉันเป็น schmuckแต่นี่คือสิ่งที่ฉันทำ:

  1. สร้าง DB จากสคริปต์ของฉันที่อยู่ในการควบคุมแหล่ง (คำใบ้คำใบ้!) หากคุณไม่มีสคริปต์คุณสามารถสร้างมันได้จากฐานข้อมูลที่มีอยู่ผ่านTasksตัวเลือก

  2. หากข้อมูลใด ๆ ที่ได้รับอัตโนมัติแทรกเข้าไปในyourdbDELETE FROM YourDB.dbo.tblYourTableที่สร้างการทำงาน

    • DELETEคุณไม่สามารถตัดข้อมูลเมื่อคีย์ต่างประเทศที่มีอยู่เพื่อให้คุณได้ใช้งาน
  3. รันสิ่งนี้บนเซิร์ฟเวอร์ปลายทางของคุณ: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all';

  4. คลิกขวาที่yourdbObject Explorerใน คลิกTasks->Import Data...

  5. หน้าจอแรก ๆ ของตัวช่วยสร้างอธิบายได้ด้วยตนเอง

  6. บนSelect Source Table and Viewsหน้าจอของตัวช่วยสร้างให้คลิกช่องทำเครื่องหมายถัดจากทุกตารางที่คุณต้องการคัดลอก

  7. สำหรับแต่ละแถว (ตาราง) Edit Mappingsบนหน้าจอที่ให้คลิกที่มันจึงเป็นไฮไลต์และจากนั้นคลิก

  8. สำหรับแต่ละแถว (ตาราง) คลิก / การตรวจสอบและAppend rows to the destination tableEnable identity insert

    • หากคุณคลิกที่Delete rows in destination tableมันจะล้มเหลวเพราะมันไม่ได้ออกDELETEคำสั่งก็จะออกTRUNCATEคำสั่งที่ยังคงขัดแย้งกับคีย์ต่างประเทศของเราเพราะTRUNCATEไม่ได้ควบคุมโดยNOCHECK CONSTRAINTจากก่อนหน้านี้
  9. Finishคลิกผ่านส่วนที่เหลือของตัวช่วยสร้างและคลิก

  10. ระวังข้อผิดพลาด ; คำเตือนอาจไม่เป็นไร

    • หากมีข้อผิดพลาดให้คลิกReportปุ่มและดูรายงาน และพยายามรู้ทันเหตุการณ์สิ่งที่เป็นSuccess, และError Stoppedคุณอาจต้องแก้ไขสิ่งที่เป็นสาเหตุของข้อผิดพลาดที่ฝังอยู่ในรายงานนั้น DELETE FROM YourDB.dbo.theErrorTableจากนั้นคุณอาจจะต้องทำ Successตอนนี้คลิกปุ่มกลับบนตัวช่วยสร้างการนำเข้าและยกเลิกการเลือกตารางที่เป็นทุก ทำซ้ำ infinitum โฆษณา
  11. รันสิ่งนี้บนเซิร์ฟเวอร์ปลายทางของคุณ: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all';

    • หากมีข้อผิดพลาด ... ฉันไม่รู้ แต่แก้ไขและลองใหม่อีกครั้ง!
  12. เย้! :)

ขอบคุณทุกคนที่ตอบคำถามนี้และคำถามที่คล้ายกันนี้ในเครือข่าย SE ที่ช่วยฉันหาทางแก้ปัญหานี้


คุณเป็นผู้ช่วยชีวิต
Tom Gullen

1
ขอบคุณมากอย่างจริงจังมีการสำรองข้อมูลในไดรฟ์ที่เสียหายไม่สามารถคัดลอกฐานข้อมูลได้ทุกที่ (ข้อผิดพลาด i / o) การนำเข้าข้อมูลตารางสองสามครั้งในลักษณะนี้ช่วยให้ฉันสามารถกู้คืนได้ 99%
Tom Gullen

1
คุณร็อค! คำสั่งอื่นที่ช่วยฉัน: EXEC sp_msforeachtable 'ลบออกจาก? '; หากมีข้อผิดพลาดเกิดขึ้นลบทุกอย่างเป็นกฎหมาย สคริปต์ sp_msforeachtable อยู่ที่นี่gist.githubusercontent.com/metaskills/893599/raw/…
Sanchitos

4

ในตัวช่วยสร้างการนำเข้าคุณสามารถลบแถวก่อนและถ้าคุณมีเขตข้อมูลตัวตนจากนั้นคุณสามารถเปิดใช้งานการแทรกตัวตนดังต่อไปนี้

ป้อนคำอธิบายรูปภาพที่นี่

หากคุณต้องการปิดการใช้งานข้อ จำกัด การตรวจสอบจากนั้นเมื่อตัวช่วยสร้างขอให้คุณบันทึกแพคเกจให้บันทึกและแก้ไขตัวจัดการการเชื่อมต่อดังต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่

หมายเหตุ: คุณไม่สามารถตัดทอนตารางได้เมื่อมีการกำหนดคีย์ต่างประเทศ


3

อย่าทิ้งข้อ จำกัด

สิ่งที่คุณควรทำคือบันทึกแพ็คเกจ SSIS ที่ตัวช่วยสร้างสร้างขึ้นจากนั้นแก้ไขใน BIDS / SSDT เมื่อคุณแก้ไขแพคเกจคุณจะสามารถควบคุมลำดับที่ประมวลผลตารางเพื่อให้คุณสามารถประมวลผลตารางหลักจากนั้นประมวลผลตารางลูกเมื่อตารางหลักทั้งหมดเสร็จสิ้น


3
นั่นไม่ได้มีประสิทธิภาพจริงๆเช่นกันมันอาจใช้เวลาเกือบชั่วโมงในขณะนี้เพื่อปรับเปลี่ยนแพคเกจเพื่อให้แน่ใจว่าทุกอย่างอยู่ในลำดับที่ถูกต้องและแม้กระทั่งตอนนั้นฉันก็ไม่แน่ใจ สิ่งนี้จะทำให้เกิดความยุ่งยากมากขึ้นเมื่อฐานข้อมูลเติบโตขึ้นและจะทำทุกครั้งไม่ต้องขอบคุณ จะต้องมีวิธีที่ง่ายในการทำเช่นนี้

1

ปัญหาเช่นนี้แสดงให้เราเห็นว่าผู้ที่สร้างเซิร์ฟเวอร์ SQL ไม่เคยใช้ผลิตภัณฑ์ของตน นี่เป็นการละเว้นการจ้องมองที่ใคร ๆ ก็ต้องสงสัยว่าพวกเขาลืมทำอะไรอย่างถูกต้อง (ฉันได้รับรายการของปัญหาน่าคลั่งอื่น ๆ อีกประมาณ 30 เรื่องเช่นนี้ที่ฉันต้องเอาชนะเพื่อให้งานนี้เป็นฐานข้อมูลอื่น ๆ รวมถึงความจริงที่ว่าเราต้องการตัวช่วยสร้างหมัดเพื่อทำสิ่งนี้ในตอนแรก [ถ้าฉันมีเวลาฉันใช้เวลารอตัวช่วยสร้างนี้เพื่อเชื่อมต่อและระบุตารางเดียวกันสำหรับฐานข้อมูลเดียวกันทุกครั้งกลับ ... ฉันมีเวลาสำหรับวันหยุดพักผ่อนที่ดี])

ฉันขี้เกียจมากและไม่ต้องการพิมพ์ EXEC sp_msforeachtable ...ทุกครั้งที่ฉันทำสิ่งนี้ งานของฉันคือการทิ้งข้อ จำกัด ไว้ในเซิร์ฟเวอร์ที่ใช้งานจริงและลบออกจากเซิร์ฟเวอร์ dev สิ่งนี้จะป้องกันข้อผิดพลาด แต่วิธีนี้มีผลข้างเคียงน้อยมาก ก่อนอื่นคุณจะไม่สามารถกู้คืนการสำรองข้อมูลเต็มรูปแบบไปยังเซิร์ฟเวอร์ dev ของคุณได้อีกต่อไป (เว้นแต่คุณจะตกลงด้วยการลบข้อมูลทั้งหมดอีกครั้ง) ประการที่สองวิธีนี้ทำงานได้ดีที่สุดเมื่อคุณมั่นใจว่าผู้บริโภคข้อมูลของคุณบังคับใช้ข้อ จำกัด เหล่านี้ (หรือไม่สนใจพวกเขา) ในกรณีของฉันเรามีผู้บริโภคเพียงคนเดียว (เว็บไซต์ของเรา) ดังนั้นเราจึงได้สร้างข้อ จำกัด เหล่านี้ลงในรหัสไซต์ด้วย (เช่นก่อนที่เราจะลบบันทึกผู้ใช้เราจะลบบันทึกโทรศัพท์ทั้งหมดสำหรับผู้ใช้รายนั้นก่อน) ใช่, สิ่งนี้ทำให้ความต้องการในการ จำกัด ในสถานที่แรกขัดแย้งกับงานที่ฉันต้องทำเพิ่มขึ้นเป็นสองเท่า แต่มันก็ทำให้ฉันมีโอกาสที่จะตรวจสอบว่ารหัสของฉันทำงานได้โดยมีหรือไม่มีข้อ จำกัด ตาม DBMS (ความจริงก็คือ เซิร์ฟเวอร์เป็นแผนฉุกเฉินเท่านั้น) คุณสามารถเรียกสิ่งนี้ว่าข้อบกพร่องในการออกแบบของฉัน แต่ฉันอยากจะเรียกมันว่าวิธีแก้ปัญหาสำหรับ DBMS ที่มีข้อบกพร่อง อย่างไรก็ตามมันก็เร็วและง่ายกว่าที่จะทำที่อื่นนอกเหนือจากจาก MSSQL เพราะไม่สามารถรับมือกับการออกแบบของตัวเองได้


0

ฉันคิดว่าคุณไม่สามารถทำการสำรองข้อมูลและกู้คืนจากเซิร์ฟเวอร์การผลิตเนื่องจากเป็นข้อมูลที่สำคัญ ถ้าไม่มีสิทธิ์ที่เหมาะสมมันยิ่งซับซ้อนมากขึ้น แต่ถ้าคุณมีการสำรองฐานข้อมูลและเรียกคืนได้แล้วคุณสามารถดำเนินการได้

มิฉะนั้นวิธีหนึ่งที่ฉันอยากจะแนะนำคือการวางข้อ จำกัด และดัชนีทั้งหมดของคุณแล้วเพิ่มอีกครั้งเมื่อนำเข้าหรือส่งออกข้อมูลแล้ว

ไม่ใช่คำตอบที่แน่นอน แต่มันจะดำเนินการอย่างรวดเร็ว


ขอบคุณ แต่ฉันบอกโดยเฉพาะว่าฉันไม่ต้องการสคริปต์ออก / สร้างสคริปต์ข้อ จำกัด

0

แค่อ่านหัวข้อนั้น มันเป็นโพสต์เก่า แต่นี่คือสิ่งที่ฉันทำเพื่อช่วยให้ผู้คนในอนาคตที่อ่านข้อความนี้

ในกรณีของฉันฉันต้องการนำเข้าตารางที่ว่างเปล่า เมื่อแก้ไขการแมปฉันเลือก<ignore>สำหรับคีย์หลัก เนื้อหาทั้งหมดของฉันถูกเพิ่มอย่างอัตโนมัติ

หวังว่าจะช่วยใครซักคน


1
เพิกเฉยคีย์หลักจะช่วยเกี่ยวกับกุญแจต่างประเทศหรือไม่
dezso

ในกรณีของฉันใช่เพราะฉันทำโต๊ะจริงๆ ดังนั้นฉันจึงจบลงด้วยคีย์หลักเดียวกัน ดังนั้นกุญแจต่างประเทศที่ชี้ไปที่ตารางของฉันยังคงสอดคล้องกับรายการที่ถูกต้อง
Greg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.