您的示例并未说明foreign_keys 的实际应用。外键约束仅在修改数据库中的数据时适用。但是你只是在做SELECT,所以PRAGMA foreign_keys的设置无关紧要。
为了说明这个 pragma 的用法,请考虑以下示例。我创建了book 和author 表,其中前者具有后者的外键:
[queue inDatabase:^(FMDatabase *db) {
success = [db executeUpdate:@"create table author (author_id integer primary key, name text)"];
if (!success) NSLog(@"Create author table failed: %@", [db lastErrorMessage]);
success = [db executeUpdate:@"create table book (book_id integer primary key, author_id integer, title text, FOREIGN KEY(author_id) REFERENCES author(author_id))"];
if (!success) NSLog(@"Create book table failed: %@", [db lastErrorMessage]);
}];
如果没有 foreign_keys 编译指示,这可行:
[queue inDatabase:^(FMDatabase *db) {
// without foreign key constraints enforced, this will succeed, even though the author_id has not yet been added to author table
success = [db executeUpdate:@"insert into book (book_id, author_id, title) values (?, ?, ?)", @(1), @(101), @"Romeo and Juliet"];
if (!success) NSLog(@"Insert 'Romeo and Juliet' failed: %@", [db lastErrorMessage]);
// obviously, this will, too
success = [db executeUpdate:@"insert into author (author_id, name) values (?, ?)", @(101), @"William Shakespeare"];
if (!success) NSLog(@"Insert 'William Shakespeare' failed: %@", [db lastErrorMessage]);
}];
但是如果我打开外键:
[queue inDatabase:^(FMDatabase *db) {
// turn on foreign keys
success = [db executeUpdate:@"PRAGMA foreign_keys = YES"];
if (!success) NSLog(@"Foreign keys pragma failed: %@", [db lastErrorMessage]);
}];
如果再试一次,book 的第一次插入没有相应的author 条目会失败。在插入 author 条目之前,我无法插入 book 条目:
[queue inDatabase:^(FMDatabase *db) {
// with foreign key this should (and does) fail
success = [db executeUpdate:@"insert into book (book_id, author_id, title) values (?, ?, ?)", @(2), @(201), @"One Hundred Years of Solitude"];
if (!success) NSLog(@"First insert of 'Hundred Years of Solitude' failed: %@", [db lastErrorMessage]);
// but if we insert author ...
success = [db executeUpdate:@"insert into author (author_id, name) values (?, ?)", @(201), @"Gabriel García Márquez"];
if (!success) NSLog(@"Insert 'Gabriel García Márquez' failed: %@", [db lastErrorMessage]);
// ... now this will succeed.
success = [db executeUpdate:@"insert into book (book_id, author_id, title) values (?, ?, ?)", @(2), @(201), @"One Hundred Years of Solitude"];
if (!success) NSLog(@"Second insert 'Hundred Years of Solitude' failed: %@", [db lastErrorMessage]);
}];