Làm cách nào để xử lý các ràng buộc FK khi nhập dữ liệu bằng Trình hướng dẫn nhập / xuất DTS?


16

Tôi đang cố gắng sử dụng Trình hướng dẫn Nhập và Xuất của Máy chủ SQL để sao chép dữ liệu từ db sản xuất sang dev db của tôi nhưng khi tôi làm điều đó không thành công với lỗi "Quy tắc INSERT đã xung đột với ràng buộc FOREIGN KEY" tôi có hơn 40 bảng với rất nhiều bảng về các ràng buộc FK, có một số cách dễ dàng để giải quyết vấn đề này mà không phải viết một ràng buộc thả / thêm tập lệnh constrat?

Chỉnh sửa: Tôi vừa phát hiện ra rằng trong phiên bản Web của SQL Server, đó là những gì tôi đang chạy, DTS sẽ không cho phép bạn lưu các gói.

Câu trả lời:


28

Tôi đã được cung cấp giải pháp này tại SQLTeam.com:

Sử dụng:

 EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

Sau đó nhập dữ liệu của bạn

EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT all'

Sử dụng phương pháp đó tôi có thể nhập tất cả dữ liệu mà không gặp vấn đề gì.


1
sp_msforeachtable(và sp_MSForEachDb) không có giấy tờ và không được hỗ trợ. Bạn không nên / tránh sử dụng nó. Nó có thể bỏ qua các bảng !! Xem bài đăng này từ @AaronBertrand -> sqlblog.com/bloss/aaron_bertrand/archive/2010/12/29/ và mục kết nối này - (MS chỉ ra rằng họ sẽ không sửa nó) -> connect.microsoft.com/QueryServer / feedback / chi tiết / 264677 / Nhận
Kin Shah

Làm việc hoàn hảo với tôi sau nhiều giờ đánh bại bộ não của tôi khi cố gắng vượt qua các ràng buộc FK để xuất dữ liệu.
levininja

Chạy trên Azure SQL V12, tôi gặp lỗi "Không thể tìm thấy quy trình được lưu trữ 'sp_msforeachtable'."
Đại

Dù sao cũng không hoạt động: /
Douglas Gaskell

Bạn là người cứu người
Có thể Şahin Bakır

5

Tôi đã tạo một bản sao chính xác của cơ sở dữ liệu trên máy của mình từ máy chủ mà tôi không kiểm soát.

Tôi là một schmuck , nhưng đây là những gì tôi đã làm:

  1. Tạo DB từ tập lệnh của tôi nằm trong kiểm soát nguồn (gợi ý, gợi ý!) Nếu bạn không có tập lệnh, bạn luôn có thể tạo tập lệnh từ DB hiện có thông qua Taskstùy chọn.

  2. Nếu bất kỳ dữ liệu nào được tự động chèn vào YourDB khi tạo, hãy chạy a DELETE FROM YourDB.dbo.tblYourTable.

    • Bạn không thể cắt dữ liệu khi khóa ngoại tồn tại để bạn phải sử dụng DELETE.
  3. Chạy cái này trên máy chủ đích của bạn: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all';

  4. Nhấp chuột phải vào YourDB trong Object Explorer. Bấm Tasks->Import Data...

  5. Một vài màn hình đầu tiên của trình hướng dẫn là tự giải thích.

  6. Trên Select Source Table and Viewsmàn hình của trình hướng dẫn, nhấp vào hộp kiểm bên cạnh mỗi bảng bạn muốn sao chép.

  7. Đối với mỗi hàng (bảng) trên màn hình đó, nhấp vào nó để nó được tô sáng và sau đó nhấp Edit Mappings.

  8. Đối với mỗi hàng (bảng), nhấp / kiểm tra Append rows to the destination tableEnable identity insert.

    • Nếu bạn nhấp vào Delete rows in destination tablenó sẽ thất bại vì nó không phát DELETElệnh, nó sẽ phát TRUNCATElệnh vẫn xung đột với khóa ngoại của chúng tôi vì TRUNCATEkhông bị chi phối bởi NOCHECK CONSTRAINTtừ trước đó.
  9. Nhấp qua phần còn lại của trình hướng dẫn và nhấp Finish.

  10. Theo dõi lỗi ; cảnh báo có lẽ là ok để bỏ qua.

    • Nếu có lỗi, nhấp vào Reportnút và xem báo cáo. Hãy thử và Suss ra những gì là một Success, ErrorStopped. Có lẽ bạn sẽ cần sửa bất cứ điều gì là nguyên nhân gốc của lỗi được chôn trong báo cáo đó ở đâu đó. Sau đó, có lẽ bạn sẽ cần phải làm một DELETE FROM YourDB.dbo.theErrorTable. Bây giờ hãy nhấp vào nút quay lại trên trình hướng dẫn nhập và bỏ chọn mọi bảng là a Success. Lặp lại quảng cáo vô hạn.
  11. Chạy cái này trên máy chủ đích của bạn: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all';

    • Nếu có lỗi, ... tôi không biết, nhưng hãy sửa chúng và thử lại!
  12. Yay! :)

Cảm ơn tất cả mọi người đã trả lời câu hỏi này và những câu hỏi tương tự như vậy trên mạng SE đã giúp tôi tìm ra câu hỏi này.


Bạn là người cứu
rỗi

1
Nghiêm túc cảm ơn bạn rất nhiều, đã sao lưu trên một ổ đĩa bị hỏng, không thể sao chép DB ở bất cứ đâu (lỗi i / o). Nhập dữ liệu một vài bảng tại một thời điểm theo cách này đã giúp tôi phục hồi 99% dữ liệu.
Tom Gullen

1
Bạn đá! Một lệnh khác đã giúp tôi: EXEC sp_msforeachtable 'xóa khỏi? '; Nếu xảy ra lỗi, hãy xóa mọi thứ là luật. kịch bản sp_msforeachtable có ở đây gist.githubusercontent.com/metaskills/893599/raw/ Kẻ
Sanchitos 23/11/18

4

Trong trình hướng dẫn nhập, bạn có thể xóa các hàng trước và nếu bạn có các trường danh tính, thì bạn có thể bật chèn nhận dạng như bên dưới

nhập mô tả hình ảnh ở đây

Nếu bạn muốn tắt ràng buộc kiểm tra, thì khi trình hướng dẫn yêu cầu bạn lưu gói, lưu nó và sau đó chỉnh sửa trình quản lý kết nối như sau:

nhập mô tả hình ảnh ở đây

Lưu ý: Bạn không thể TRUNCATE bảng khi có Khóa ngoại được xác định.


3

Đừng bỏ qua các ràng buộc.

Điều bạn nên làm là lưu gói SSIS mà trình hướng dẫn tạo, sau đó chỉnh sửa nó trong BIDS / SSDT. Khi bạn chỉnh sửa gói, bạn sẽ có thể kiểm soát thứ tự các bảng được xử lý để bạn có thể xử lý các bảng cha sau đó xử lý các bảng con khi tất cả các bảng cha được thực hiện.


3
Điều đó cũng không thực sự hiệu quả, phải mất gần một giờ để sửa đổi gói để đảm bảo mọi thứ đều đúng thứ tự, và thậm chí sau đó tôi không thể chắc chắn. Điều này sẽ trở nên cồng kềnh hơn khi DB phát triển và làm điều đó mọi lúc, không cần cảm ơn. Phải có một cách đơn giản để làm điều này.

1

Các vấn đề như thế này cho chúng ta thấy rằng những người tạo ra máy chủ SQL chưa bao giờ thực sự sử dụng sản phẩm của họ. Đây là một thiếu sót to lớn đến nỗi người ta phải tự hỏi họ còn quên làm gì nữa một cách chính xác (Tôi đã có một danh sách khoảng 30 vấn đề điên rồ khác như thế này mà tôi phải khắc phục để làm việc này khi các DB khác giải quyết của hộp, bao gồm cả việc chúng ta cần một thuật sĩ tệ hại để làm điều này ngay từ đầu [nếu tôi có thời gian chờ đợi thuật sĩ này kết nối và liệt kê các bảng giống nhau cho cùng một DB, mọi lúc, trở lại ... Tôi sẽ có thời gian cho một kỳ nghỉ tốt đẹp]).

Tôi rất lười biếng và không muốn gõ EXEC sp_msforeachtable ...hai lần mỗi lần tôi làm điều này Công việc của tôi là để lại các ràng buộc trên máy chủ sản xuất và xóa chúng khỏi máy chủ dev. Điều này sẽ ngăn chặn lỗi nhưng phương pháp này có một vài tác dụng phụ RẤT LỚN. Đầu tiên, bạn sẽ không còn có thể khôi phục lại bản sao lưu đầy đủ cho máy chủ dev của mình (trừ khi bạn ổn với việc xóa tất cả chúng một lần nữa). Thứ hai, điều này hoạt động tốt nhất khi bạn chắc chắn rằng người tiêu dùng dữ liệu của bạn cũng thực thi các ràng buộc này (hoặc không quan tâm đến chúng). Trong trường hợp của tôi, chúng tôi chỉ có một người tiêu dùng (trang web của chúng tôi) vì vậy chúng tôi cũng đã xây dựng các ràng buộc này vào mã trang web (tức là trước khi xóa bản ghi người dùng, chúng tôi sẽ xóa tất cả các bản ghi điện thoại cho người dùng đó trước). Đúng, điều này về cơ bản phủ nhận sự cần thiết của các ràng buộc ở nơi đầu tiên và tăng gấp đôi công việc tôi cần làm nhưng nó cũng cho tôi cơ hội để xác minh rằng mã của tôi hoạt động có hoặc không có các ràng buộc dựa trên DBMS (thực tế là chúng vẫn còn trên prod máy chủ chỉ là một kế hoạch dự phòng). Bạn có thể gọi đây là một lỗ hổng trong thiết kế của tôi nhưng tôi muốn gọi nó là một cách giải quyết cho một DBMS thiếu sót. Ở bất cứ giá nào, nó vẫn nhanh hơn và dễ dàng hơn để làm điều này ở bất cứ nơi nào khác ngoài từ trong MSSQL vì không thể đối phó với thiết kế của chính nó.


0

Tôi nghĩ bạn không thể thực hiện sao lưu và khôi phục từ máy chủ sản xuất vì đây là dữ liệu quan trọng. Không có các quyền thích hợp, nó thực sự trở nên phức tạp hơn. Nhưng nếu bạn có db backup n restore ngay thì bạn có thể thực hiện nó.

Hoặc nếu không, Một cách mà tôi muốn giới thiệu là bỏ tất cả các ràng buộc và chỉ mục của bạn và sau đó thêm lại chúng sau khi dữ liệu đã được nhập hoặc xuất.

Không phải là một câu trả lời chính xác nhưng nó sẽ xử lý nhanh.


Cảm ơn, nhưng tôi nói cụ thể là tôi không muốn tạo ra một kịch bản ràng buộc thả / tạo.

0

Chỉ cần đọc chủ đề đó. Đây là một bài viết cũ nhưng đây là những gì tôi đã làm để giúp những người tương lai đọc nó.

Trong trường hợp của tôi, tôi muốn nhập vào một bảng giống hệt trống. Khi chỉnh sửa ánh xạ, tôi chọn <ignore>khóa chính. Tất cả nội dung của tôi đang được thêm tự động độc đáo.

Hy vọng nó sẽ giúp được ai đó


1
Bỏ qua khóa chính sẽ giúp với khóa ngoại?
dezso

Trong trường hợp của tôi, có vì tôi đã thực sự sao chép một bảng. Vì vậy, tôi đã kết thúc với các khóa chính tương tự. Vì vậy, các khóa ngoại trỏ vào bảng của tôi vẫn tương ứng với mục nhập chính xác
Greg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.