我正在开发一个支持SQLite数据库的Android 2.2+应用。我正在尝试在创建表时定义参照完整性约束。我还通过db.execSQL( "PRAGMA foreign_keys=ON;" );
和onCreate
onOpen
方法执行SQLiteOpenHelper
来启用外键支持。在设置我的表和正确的外键引用后,它仍允许我在缺少引用记录的表中insert
行。对于例如我有以下结构
CREATE TABLE Questions(_id integer primary key,question text not null);
CREATE TABLE Ques_Ans(_id integer primary key autoincrement,qid integer not null,
aid integer not null,is_correct integer default 0,
FOREIGN KEY (qid) REFERENCES Questions(_id));
并按照表格中的数据
INSERT INTO Questions VALUES(1, 'Some text');
INSERT INTO Ques_Ans(qid, aid, is_correct) VALUES(20, 1, 0);
如果在Ques_Ans表上正确设置了外键,则第二个插入应该失败,因为Questions
表中没有id为20
的记录,但不知怎的,我的应用程序没有抛出任何错误并插入第二个插入声明。谁能告诉我这里有什么问题,或者我错过了这里的任何配置?
更新[2012年3月3日]:与@Catcall讨论后讨论
sqlite3
工具,启用PRAGMA foreign_keys=ON;
外键按预期工作insert()
或execSQL()
执行的语句。他们都没有抛出foreign key constraint failed
错误PRAGMA integrity_check
返回ok
。所以数据库没有损坏。答案 0 :(得分:1)
您的外键位于“qid”列,而不是“_id”列。
此INSERT语句
INSERT INTO Ques_Ans VALUES(20, 1, 0);
应该抛出错误
Error: table Ques_Ans has 4 columns but 3 values were supplied
此INSERT应该会成功。
INSERT INTO Ques_Ans VALUES(20, 1, 0, 0);
这个应该失败。
INSERT INTO Ques_Ans VALUES(21, 2, 0, 0);
Error: foreign key constraint failed
后来。 。
由于它适用于sqlite,但不适用于您的模拟器,因此问题可能出在模拟器或代码中。
这是数据库事务的习惯用法。
db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
Android文档建议使用insert()代替execSQL()。确保在每个可以返回错误的函数中捕获,捕获或检查错误。因此,例如,如果切换到insert(),请检查其返回值为-1。
如果这没有帮助,您可以尝试使用“Java”标记此问题(例如),或者询问一个专注于您的代码和捕获错误的新问题。
答案 1 :(得分:0)
IN SQLite默认情况下禁用外键约束(为了向后兼容)。您必须使用
明确启用它PRAGMA foreign_keys = 1 与数据库建立连接后。这里是官方文档的链接,可以更深入地解释它。 http://sqlite.org/foreignkeys.html请导航到上述链接中启用外键支持。