SQLite:为什么外键约束在这里不起作用?

时间:2016-11-29 10:15:43

标签: sql sqlite

基于https://www.sqlite.org/foreignkeys.html我认为在SQLite中执行时,我会在SQL的最后一行得到一个外键约束错误,但它只是吞下它并继续前进。那是为什么?

CREATE TABLE Person ( 
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(100)
);

CREATE TABLE Child (
    parent_id INTEGER,
    child_id INTEGER,

    FOREIGN KEY (parent_id) REFERENCES Person(id),
    FOREIGN KEY (child_id) REFERENCES Person(id)
);

INSERT INTO Person(name) 
       VALUES ('John Doe');
INSERT INTO Person(name) 
       VALUES ('Clara Doe');

INSERT INTO Child(parent_id, child_id) VALUES (45, 50);

3 个答案:

答案 0 :(得分:4)

您需要先启用foreign key enforcement

PRAGMA foreign_keys=on;

答案 1 :(得分:1)

https://www.sqlite.org/foreignkeys.html

  
      
  1. 启用外键支持
  2.         

    为了在SQLite中使用外键约束,库必须是   既不用SQLITE_OMIT_FOREIGN_KEY也不用SQLITE_OMIT_TRIGGER编译   定义。如果定义了SQLITE_OMIT_TRIGGER但SQLITE_OMIT_FOREIGN_KEY   不是,然后SQLite的行为与版本3.6.19之前的行为相同   (2009-10-14) - 解析外键定义并可以查询   使用PRAGMA foreign_key_list,但外键约束不是   强制执行。 PRAGMA foreign_keys命令在此无操作   组态。如果定义了OMIT_FOREIGN_KEY,则为外键   甚至无法解析定义(尝试指定外键)   定义是语法错误。)

https://www.sqlite.org/pragma.html#pragma_foreign_keys

  

PRAGMA foreign_keys; PRAGMA foreign_keys =布尔值;

     

查询,设置或清除外键约束的强制执行。

     

此pragma是交易中的无操作;外键约束   只有在没有待处理时才可以启用或禁用强制执行   开始或SAVEPOINT。

     

更改foreign_keys设置会影响所有的执行   使用数据库连接准备的语句,包括那些   在设置改变之前准备好。任何现有的陈述   使用遗留的sqlite3_prepare()接口准备可能会失败   foreign_keys设置更改后SQLITE_SCHEMA错误。

     

从SQLite版本3.6.19开始,外键的默认设置   执法是关闭的。但是,这可能会在将来的版本中发生变化   SQLite的。外键实施的默认设置可以是   使用SQLITE_DEFAULT_FOREIGN_KEYS在编译时指定   预处理器宏。为了最大限度地减少未来的问   根据应用程序的要求设置外键执行标志   而不依赖于默认设置。

sqlite> create table t1 (i int primary key);
sqlite> create table t2 (j references t1(i));
sqlite> insert into t2 values (1);
sqlite> PRAGMA foreign_keys=on;
sqlite> insert into t2 values (1);
Error: FOREIGN KEY constraint failed

答案 2 :(得分:1)

您可以强制执行以下外键:

CREATE TABLE歌曲(   songid INTEGER,   歌手TEXT,   songalbum文字,   歌名TEXT,   FOREIGN KEY(歌手,songalbum)REFERENCES专辑(albumartist,albumname) );