Delete Item mà có khoá ngoại ở bảng khác

c-sharp
sql-server

(Giang Thùy Nguyên) #1

Các anh cho em hỏi là làm sao để xóa ITEM mà có khóa ngoại ở bảng khác , trường hợp của em là em có 1 bảng ITEM với ITEM_ID đc set identity, bảng order sẽ có 1 bảng detail bên trong và detail đó có khóa ngoại là ITEM_ID , cho nên mỗi lần em xóa sản phẩm bên bảng ITEM thì nó sẽ xảy ra lỗi do có foreign key ở bảng Detail, các anh có cách nào giúp em khắc phục vấn đề này không ạ ?, by the way em đang dùng C# và SQL server . Em xin cảm ơn ạ ! :grinning:


(vũ xuân quân) #2

Nếu quan hệ 1-1 thì phải xóa luôn data của 2 bảng Item và Order.
Nếu quan hệ n-n thì xóa bảng chính (Item) và bảng phụ (chứa khóa của 2 bảng item và oder)


(Trần Hoàn) #3

Nhìn nhận 1 cách khách quan, khi 1 bảng sử dụng khoá ngoại tức là 1 trường đang trỏ đến 1 thực thể mẫu đã tồn tại. Như vậy, nếu như thực thể đó biến mất thì tất cả những gì đang trỏ đến thực thể đó sẽ phải biến mất theo hoặc phải thay đổi để không còn trỏ đến thực thể đó nữa.

Cho nên đối với các thực thể mẫu (ví dụ các record trong bảng ITEM) thì ta sẽ không xoá nó bằng 1 thao tác thông thường (delete from ITEM where ...) mà phải bằng một query batch (xoá hoặc chuyển tất cả các đoạn trỏ đến item bị xoá thành UNDEFINED…) và câu query xoá kia ở cuối cùng.


(Thai Pham) #4

Giả sử rằng table Item của bạn chỉ có khoá ngoại ở table OrderDetail và quan hệ giữa 2 table này là 1-1 hoặc 1-n chứ không phải n-n, bạn có thể dùng một trong hai cách:

  • Dùng 1 query để tìm và delete các record từ table OrderDetail trước và sau đó dùng 1 query khác để delete các record từ table Item (theo hướng dẫn của @masoivn@noz1995 ).
  • Dùng tham số DELETE CASCADE khi tạo khóa ngoại ở bảng OrderDetail. Cách làm cụ thể bạn có thể tham khảo ở đây:

Khi dùng DELETE CASCADE, bạn có thể delete trực tiếp từ table Item. SQL Server sẽ tự động dò tìm và delete các record phụ thuộc trong table OrderDetail. (Lưu ý là hướng dẫn trên chỉ là cho SQL Server, đối với các hệ CSDL khác thì cách làm có thể hơi khác một chút - theo như tôi biết thì MySQL và PostgreSQL cũng có hỗ trợ DELETE CASCADE nhưng cách khai báo và thực hiện hơi khác).

Trong trường hợp liên hệ giữa hai table của bạn là n-n có nghĩa là phải có table trung gian để quản lý các khóa, thì bạn phải delete từ table trung gian trước rồi mới đến delete trên các table này được. Nguyên tắc chung là bao giờ cũng bắt đầu delete từ các table phụ thuộc (có chứa khoá ngoại) rồi mới đến các table có khóa chính (primary key).


(Hai Lúa) #5

Về nguyên tắc khi xóa dữ liệu trong tables, bao giờ cũng phải xóa dữ liệu ở bảng con trước, sau đó mới xóa dữ liệu ở bảng cha.

Hầu hết các CSDL phổ biến hiện nay điều hổ trợ sử dụng ON DELETE CASCADE hoặc ON DELETE SET NULL. Tuy nhiên trong thực tế ít khi xài vì nó “tiện lợi” quá, lỡ xóa nhầm 1 row là nó đi luôn cả dây. VD bạn xóa nhầm 1 row ở bảng Danh mục Phòng Ban, coi như cả cái phòng ban đó lẫn Nhân viên,… lên đường hết !

Để tìm hiểu thêm về Foreign Key trên SQL Server bạn có thể tham khảo link bên dưới.

[Tự học SQL SERVER] Bài 12: CONSTRAINTS, Hướng dẫn tạo, minh họa 5 loại Constraints trên SQL Server. <= FK Key ở phút 19:30


83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?