2014-12-19 14 views
6

Tôi có ví dụ sau:CASCADE DELETE trên hai ràng buộc khoá ngoại

Table A 
    -some_id 

Table B 
    -another_id 

Table C 
    -some_id_fk 
    -another_id_fk 

Tôi muốn thác liên tiếp trên Table C nếu cả hai some_idanother_id sẽ bị xóa khỏi bảng tương ứng của họ.

Làm cách nào để tạo một hàng trong Bảng C khi nó bị xóa?

Nếu chỉ một trong các FK bị xóa, hàng bị ảnh hưởng sẽ thay đổi thành giá trị rỗng trong cột tham chiếu khóa ngoài đó.

+2

Điều gì sẽ xảy ra khi chỉ một trong các hàng được tham chiếu bị xóa? Đặt FK thành 'NULL'? –

+2

Viết hai trình kích hoạt ON DELETE cho bảng A và B để xóa một hàng khỏi bảng C nếu cần. Hoặc tốt hơn hãy viết hai thủ tục để xóa các hàng từ bảng A và B và loại bỏ một hàng khỏi bảng C nếu cần. – Hovo

+0

@Hovo Tôi biết những người khởi xướng là một lựa chọn nhưng hy vọng có một giải pháp tốt hơn – 12preschph

Trả lời

5

Tôi đề nghị hai foreign key constraints with ON DELETE SET NULL và kích hoạt mà sẽ chăm sóc phần còn lại

Bàn:

CREATE TABLE a (a_id serial PRIMARY KEY, a text NOT NULL); 
CREATE TABLE b (b_id serial PRIMARY KEY, b text NOT NULL); 

CREATE TABLE ab (
    ab_id serial PRIMARY KEY 
, a_id int REFERENCES a ON DELETE SET NULL 
, b_id int REFERENCES b ON DELETE SET NULL 
, UNIQUE (a_id, b_id) 
); 

Trigger:

CREATE OR REPLACE FUNCTION trg_ab_upbef_nulldel() 
    RETURNS trigger AS 
$func$ 
BEGIN 
DELETE FROM ab WHERE ab_id = NEW.ab_id; 
RETURN NULL; 
END 
$func$ LANGUAGE plpgsql; 

CREATE TRIGGER upbef_nulldel 
BEFORE UPDATE OF a_id, b_id ON ab 
FOR EACH ROW 
WHEN (NEW.a_id IS NULL AND 
     NEW.b_id IS NULL) 
EXECUTE PROCEDURE trg_ab_upbef_nulldel(); 

SQL Fiddle.

  • Đảm bảo có cột PK thay thế cho bảng kết nối. (a_id, b_id) không thể là PK anyway, bởi vì điều đó sẽ không cho phép NULL trong cả hai. Thay vào đó, hãy thêm UNIQUE constraint, cho phép giá trị NULL.

  • Trình kích hoạt được tối ưu hóa cho hiệu suất và chỉ khởi động khi một trong hai cột FK được cập nhật và chỉ khi kết quả là cả hai là NULL.

  • Chức năng kích hoạt là tầm thường: xóa hàng và trả về NULL để hủy bỏ khoảng trống bị hủy UPDATE.

+0

Tôi muốn tất cả các câu trả lời đều có chất lượng đó. Danke! – Matthieu

Các vấn đề liên quan