2011-08-04 106 views
16

我試圖設置一個SQLite3數據庫foo s和bar s和他們之間的多對多關係。這是我到目前爲止:SQLite多對多的關係?

CREATE TABLE foo(
    id INTEGER PRIMARY KEY NOT NULL, 
    foo_col INTEGER NOT NULL 
); 
CREATE TABLE bar(
    id INTEGER PRIMARY KEY NOT NULL, 
    bar_col TEXT NOT NULL 
); 
CREATE TABLE foobar(
    foo_id INTEGER, 
    bar_id INTEGER, 
    FOREIGN KEY(foo_id) REFERENCES foo(id) ON DELETE CASCADE, 
    FOREIGN KEY(bar_id) REFERENCES bar(id) ON DELETE CASCADE 
); 
CREATE INDEX fooindex ON foobar(foo_id); 
CREATE INDEX tagindex ON foobar(tag_id); 

...但它似乎並沒有工作。我可以從foo刪除一行,但不會影響foobar。我究竟做錯了什麼?

回答

13

來自這個網站,http://www.sqlite.org/foreignkeys.html

假設庫已啓用外鍵約束編譯,它仍然必須由應用程序在運行時使用PRAGMA foreign_keys命令啓用。例如:

sqlite> PRAGMA foreign_keys = ON; 

外鍵約束默認(向後兼容)禁用,所以必須分別對每個數據庫連接單獨啓用。 (但是,請注意,未來的SQLite版本可能會更改,以便默認情況下啓用外鍵約束。仔細的開發人員不會假定是否默認啓用外鍵,而是根據需要啓用或禁用它們。)應用程序也可以使用PRAGMA foreign_keys語句來確定當前是否啓用了外鍵。下面的命令行會話演示此:

sqlite> PRAGMA foreign_keys; 
0 
sqlite> PRAGMA foreign_keys = ON; 
sqlite> PRAGMA foreign_keys; 
1 
sqlite> PRAGMA foreign_keys = OFF; 
sqlite> PRAGMA foreign_keys; 
0 

提示:如果命令「PRAGMA foreign_keys」沒有返回數據而不是包含「0」或「1」的單個行的,然後SQLite的版本使用的是不支持外鍵(或者是因爲它早於3.6.19,或者是因爲它是使用SQLITE_OMIT_FOREIGN_KEY或SQLITE_OMIT_TRIGGER定義的)編譯的。

無法在多語句事務中啓用或禁用外鍵約束(當SQLite未處於自動提交模式時)。試圖這樣做不會返回錯誤;它根本沒有效果。

+0

表foobar也可能需要(foo_id,bar_id)上的主鍵約束。但這是一個不同的問題。 –

+0

@Catcall:隨時評論我的帖子。 – wes

+0

ace的答案,直接來自SQLite文檔,是準確和完整的。但正如我所說,表foobar也需要'PRIMARY KEY(foo_id,bar_id)'。 –