2013-07-01 95 views
1

關係:students (1 can have N) addresses更新同一個表中存儲過程更新後和INSERT

場景:學生可以有很多記錄,但只有一個相關記錄必須有「current」字段設置爲「Yes」(等價值是NULL),所以下面的查詢應該每個學生總是隻返回一條記錄。

SELECT * FROM address WHERE student_id = 5 AND current = 'Yes' 

問題: 人們有時標記多個記錄爲INSERT或UPDATE對同一個學生後「是」,所以我需要避免。在MySQL中使用觸發器或存儲過程的最佳方式是什麼?

如果UPDATE在「地址」表會發生那麼這應該某處運行,以紀念其他記錄爲NULL:UPDATE addresses SET current = NULL WHERE student_id = IN_student_id

如果INSERT發生在「地址」表那麼這應該某處運行,以紀念其他記錄爲NULL:UPDATE addresses SET current = NULL WHERE student_id = IN_student_id AND id <> IN_inserted_id

在此先感謝

回答

3

如果你需要的東西自動數據被修改後更新,正確的做法是一個觸發器。注意觸發器可能會調用存儲過程。

然而,你將無法實現在觸發because描述的行爲:

存儲函數或觸發器不能由語句修改已被使用(讀或寫)的表調用函數或觸發器。

事實上,在信息「地址X是當前地址」應該被存儲在students表中的列,作爲一個外鍵address表。因此,唯一性是有保證的。

像這樣(fiddle with it here):

CREATE TABLE student (
    id INT NOT NULL PRIMARY KEY, 
    current_address INT, 
    name VARCHAR(20) 
); 

CREATE TABLE address (
    id INT NOT NULL PRIMARY KEY, 
    student_id INT NOT NULL, 
    contents VARCHAR(50) NOT NULL, 
    CONSTRAINT student_fk FOREIGN KEY student_fk_idx (student_id) 
    REFERENCES student(id) 
); 

ALTER TABLE student 
    ADD CONSTRAINT curraddr_fk_idx 
    FOREIGN KEY curraddr_fk_idx (id, current_address) 
    REFERENCES address(student_id, id); 

聲明本結構允許students插入無 「當前地址」。這是因爲兩個表中至少有一個必須允許其外鍵的值爲NULL(否則我們無法在任何表中添加單個行)。如果更有意義,則可以使用address.student_id代替NULL,並且允許address成爲別人的地址,直到您創建相應的student

+0

將地址表的PK存儲爲學生表中的當前值是個不錯的主意。謝謝 – BentCoder