2012-03-22 30 views
6

Tôi có ba bảng, hãy gọi cho họ GRANDPARENT, PARENTCHILD. PARENT có cột FK để PK của GRANDPARENTCHILD có cột FK để PK của PARENT. Càng xa càng tốt.Cách thiết lập chế độ xem có thể cập nhật bằng cách tham gia Firebird?

Bây giờ tôi muốn thiết lập chế độ xem chứa tất cả thông tin trong CHILD, cộng với PK từ GRANDPARENT. Vì vậy:

CREATE VIEW CHILD_VIEW 
(
    ID, 
    PARENT_ID, 
    OTHER_STUFF, 
    GRANDPARENT_ID 
) 
AS 
SELECT 
    C.ID, 
    C.PARENT_ID, 
    C.OTHER_STUFF, 
    C.GRANDPARENT_ID 
FROM CHILD C 
join PARENT P on P.ID = C.PARENT_ID; 

Không quá khó. Nhưng đây là phần phức tạp: Tôi muốn có thể INSERT hoặc UPDATE cho chế độ xem này và có tất cả dữ liệu có liên quan được ghi vào bảng CHILD và giá trị GRANDPARENT_ID, nếu có, sẽ bị bỏ qua.

Tôi đã thực hiện một số Googling và dường như có thể thiết lập chế độ xem có thể cập nhật như thế này "bằng cách sử dụng trình kích hoạt", nhưng nó không giải thích bất cứ nơi nào tôi phải làm với trình kích hoạt để đạt được hiệu ứng này. Tôi nghĩ rằng tôi biết nhiều hơn hoặc ít hơn làm thế nào để xử lý các trường hợp INSERT, nhưng những gì về trường hợp UPDATE? Các tuyên bố UPDATE có điều khoản WHERE và có thể chứa hoặc không chứa bất kỳ cột tùy ý nào trong bảng.

Ví dụ: làm cách nào để sử dụng trình kích hoạt để biến đổi một cái gì đó như update CHILD_VIEW set (blah blah blah) where ID = 5 thành update CHILD set (blah blah blah excluding GRANDPARENT_ID) where ID = 5?

+0

Tốt câu hỏi này về 'cái UPDATE' chỉ một số cột ... AFAIK không có cách nào để phát hiện các cột nào được bao gồm trong câu lệnh 'UPDATE' gây ra kích hoạt' ON UPDATE' để kích hoạt. Tôi nghĩ rằng đây là giá trị yêu cầu tính năng trong trình theo dõi Firebird, nếu chưa có. – ain

+0

Không nên trong mã của bạn 'C.GRANDPARENT_ID' là' P.GRANDPARENT_ID'? – EMBarbosa

+0

không có chế độ xem nhiều bảng 'INSERT' /' UPDATE's? booooo! –

Trả lời

6

Vâng, bạn làm điều đó bằng cách sử dụng gây nên, như bạn đã phát hiện ra :)

Nó thực sự là đơn giản, bạn có thể sử dụng tất cả các tính năng có sẵn trong trigger (tức OLDNEW bối cảnh) ... nếu bạn đang sử dụng Firebird 2.1 hoặc mới hơn thì bạn có thể sử dụng câu lệnh UPDATE OR INSERT hoặc bạn có thể sử dụng các biến ngữ cảnh INSERTINGUPDATING để phát hiện là nó cập nhật hoặc chèn vào trình kích hoạt đa tác vụ. Hoặc, tất nhiên, bạn có thể viết riêng ON UPDATEON INSERT trigger ...

Vì vậy, kích hoạt của bạn có thể trông giống như

CREATE TRIGGER CHILD_VIEW_Save FOR CHILD_VIEW 
ACTIVE BEFORE INSERT OR UPDATE POSITION 10 
AS 
BEGIN 
    IF(NEW.ID IS NULL)THEN NEW.ID = GEN_ID(GEN_Child, 1); 
    UPDATE OR INSERT INTO CHILD (ID, PARENT_ID, OTHER_STUFF, GRANDPARENT_ID) 
      VALUES(NEW.ID, NEW.PARENT_ID, NEW.OTHER_STUFF, NEW.GRANDPARENT_ID); 
END 
+0

... và điều gì về mệnh đề WHERE khi nó là 'UPDATE'? –

+2

Điều gì về nó? Nếu bạn có nghĩa là 'where' trong' UPDATE CHILD_View WHERE' thì bạn không quan tâm đến nó trong trigger (trigger sẽ được kích hoạt cho mỗi hàng phù hợp), nếu bạn ngụ ý 'WHERE'" bên trong trigger "thì sử dụng 'UPDATE OR INSERT' hoặc tự viết mệnh đề WHERE (bạn biết PK của bảng bạn sắp cập nhật bên trong trigger). – ain

+0

OK, điểm tốt trên PK. Điều khó khăn khác là 'UPDATE' không cập nhật toàn bộ tập hợp cột. Nếu tôi có 5 cột trong bảng và câu lệnh UPDATE chỉ đặt 3 cột, thì kích hoạt chăn sẽ giống như ví dụ của bạn làm gì với hai cột khác? –

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