Câu lệnh XÓA đã mâu thuẫn với ràng buộc TÀI LIỆU THAM KHẢO


10

Tôi đang cố gắng xóa tất cả người dùng nhưng gặp lỗi:

Msg 547, Level 16, State 0, Line 1
The DELETE statement conflicted with the REFERENCE constraint "FK_M02ArticlePersons_M06Persons". The conflict occurred in database "workdemo.no", table "dbo.M02ArticlePersons", column 'M06PersonId'.
The statement has been terminated.

Truy vấn:

DELETE FROM [workdemo.no].[dbo].[M06Persons] 
WHERE ID > '13'
GO

Có vẻ tôi cần sử dụng on delete cascade;nhưng tôi bị mắc kẹt.

Câu trả lời:


18

Bạn không cần phải sử dụng tầng xóa. Ai đó (tác giả thiết kế lược đồ) đã đảm bảo bạn không thể xóa một người vẫn được tham chiếu bởi một bài viết. Nó đã thành công, bạn chỉ đang cố gắng để làm điều này và đã bị chặn, danh tiếng cho nhà thiết kế.

Bây giờ hãy nói chuyện với ai đó đã thiết kế lược đồ và biết các ràng buộc và hỏi anh ta cách xóa đúng các bản ghi bạn đang cố xóa, theo đúng thứ tự và thực hiện các biện pháp phòng ngừa thích hợp để giữ cho cơ sở dữ liệu nhất quán.


9

Bạn có hai lựa chọn thực sự ở đây, bạn có thể vô hiệu hóa các ràng buộc trên bảng. Đây thường không phải là một ý tưởng tuyệt vời vì bạn có thể gặp phải tình trạng dữ liệu xấu nếu bạn làm rối dữ liệu liên quan đến các bảng khác, nhưng không biết toàn bộ phạm vi của lược đồ của bạn và nó có thể phù hợp với mục đích của bạn:

ALTER TABLE [workdemo.no].[dbo].[M06Persons] NOCHECK CONSTRAINT [FK_M02ArticlePersons_M06Persons]

Nhớ bật lại các ràng buộc sau khi xóa bằng

ALTER TABLE [workdemo.no].[dbo].[M06Persons] WITH CHECK CHECK CONSTRAINT [FK_M02ArticlePersons_M06Persons]

Lựa chọn thứ hai sẽ là thả và thêm lại các ràng buộc với tùy chọn BẬT XÓA CASCADE bằng cách sử dụng:

ALTER TABLE [workdemo.no].[dbo].[M06Persons] DROP CONSTRAINT [FK_M02ArticlePersons_M06Persons]

ALTER TABLE [workdemo.no].[dbo].[M06Persons] WITH NOCHECK ADD CONSTRAINT [FK_M02ArticlePersons_M06Persons] FOREIGN KEY(M06PersonId)
REFERENCES <parent table here> (<parent column here>)
ON DELETE CASCADE

Dựa trên tên FK của bạn, có vẻ như bảng cha của bạn là M02ArticlePersons và cột cha là M06Persons.

Nếu bạn không tạo ra lược đồ này, hãy thử xem xét tại sao các ràng buộc có thể xuất hiện và hiểu rằng việc vi phạm chúng theo cách này có thể có tác dụng phụ ngoài ý muốn.


2

Bảng dbo.M02ArticlePersons của cột M06PersonId được giới thiệu trong một bảng khác. Vì vậy, trước khi xóa câu lệnh, hãy tắt các mối quan hệ này và thử lại

bên dưới là để tháo khóa ngoại

 ALTER TABLE dbo.M02ArticlePersons NOCHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

DELETE FROM [workdemo.no].[dbo].[M06Persons] 
  WHERE ID > '13'
GO

và điều này là để cho phép nó

ALTER TABLE dbo.M02ArticlePersons CHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

Hy vọng điều này sẽ làm việc


2
đề nghị kinh khủng. Bạn KHÔNG BAO GIỜ nên vô hiệu hóa một ràng buộc FK cho dù bạn là một dba cao cấp (trong trường hợp bạn sẽ không có câu hỏi bằng văn bản ở trên). Những ràng buộc đó là ở đó để ngăn bạn xóa các hồ sơ. Vô hiệu hóa chúng willy nilly sẽ cung cấp cho bạn dữ liệu xấu trong cơ sở dữ liệu của bạn. Bạn được khuyến nghị một thực hành tồi tệ nhất không phải là một thực hành tốt.
HLGEM

1

Có một tùy chọn thủ công khác nữa:

Bạn có thể đi đến bảng con và xóa các hàng con được tham chiếu bởi khóa cha. Sau đó, bạn có thể xóa hàng cha mẹ. Đây thực chất là những gì các tầng xóa xóa làm. Bằng cách này, bạn không phải bỏ / tạo lại / thay đổi các ràng buộc của mình.


1

Mã nhỏ này sẽ giúp cho bất kỳ bảng nào bạn muốn xóa các bản ghi từ đó. Nó cũng quan tâm đến tính toàn vẹn tham chiếu ...

Mã bên dưới sẽ tạo ra các câu lệnh XÓA .. Chỉ cần xác định lược đồ.table_Name

Declare @sql1 varchar(max)
      , @ptn1 varchar(200)
      , @ctn1 varchar(200)
      , @ptn2 varchar(200)
      , @ctn2 varchar(200)
--
SET @ptn1 = ''
--
SET @ctn1 = ''
--
SET @ptn2 = ''
--
SET @ctn2 = ''
--
SELECT @sql1 = case when (@ptn1 <> OBJECT_NAME (f.referenced_object_id)) then
                         COALESCE( @sql1 + char(10), '') + 'DELETE' + char(10) + ' ' + OBJECT_NAME (f.referenced_object_id) + ' FROM ' + OBJECT_NAME(f.parent_object_id) + ', '+OBJECT_NAME (f.referenced_object_id) + char(10) +' WHERE ' + OBJECT_NAME(f.parent_object_id) + '.' + COL_NAME(fc.parent_object_id, fc.parent_column_id) +'='+OBJECT_NAME (f.referenced_object_id)+'.'+COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                    else
                         @sql1 + ' AND ' + OBJECT_NAME(f.parent_object_id) + '.' + COL_NAME(fc.parent_object_id, fc.parent_column_id) +'='+OBJECT_NAME (f.referenced_object_id)+'.'+COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                    end + char(10)
     , @ptn1 = OBJECT_NAME (f.referenced_object_id)
     , @ptn2  = object_name(f.parent_object_id)
FROM   sys.foreign_keys AS f
       INNER JOIN
       sys.foreign_key_columns AS fc ON f.object_id = fc.constraint_object_id
WHERE  f.parent_object_id = OBJECT_ID('dbo.M06Persons'); -- CHANGE here schema.table_name
--
print  '--Table Depended on ' + @ptn2 + char(10) + @sql1
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.