sqlite3_step返回SQLITE_CONSTRAINT

时间:2013-09-02 21:45:11

标签: ios sql sqlite indexing

我的iOS应用程序中有一个本地SQLite3数据库。

通常一切都按需要运行,但有时当我尝试SQLITE_CONSTRAINT我的表中的insert新记录时,我会收到一个奇怪的错误(sqlite3_step(statement)),并调用CREATE TABLE MyTable ( reference text PRIMARY KEY not null collate nocase, value text not null collate nocase) 方法。在删除表并再次重新创建表之后会发生这种情况。(是的,我需要删除表并重新创建,而不仅仅是删除我的所有记录)。


以下是我创建表的方法。

"sqlite_autoindex_mytable_1"

我的表没有任何创建的手动索引,只是自动生成唯一索引sqlite3_stmt *statement; int result = sqlite3_prepare_v2(database, [sqlString UTF8String], -1, &statement, NULL); if (result == SQLITE_OK) { int sql_result = sqlite3_step(statement); // here is receive sql_result == SQLITE_CONSTRAINT (19) } 。当我阅读here(lang_creatable)时,这是正常的情况。


以下是一些代码:

SQLITE_CONSTRAINT

问题不一定在sql查询字符串中。正如我也读到的,当我尝试插入一些具有相同主键的记录时,我可以收到此错误。在我的情况下,我有一个空表并收到此错误。

所以问题是导致{{1}}错误的原因是什么?删除表后仍然可以删除唯一索引但仍包含一些信息吗?

1 个答案:

答案 0 :(得分:3)

您应该查看sqlite3_errmsg返回的错误消息,它将准确地告诉您哪个约束失败以及插入失败的原因。它可能会报告

  • “列引用不是唯一的” - 当您尝试插入的reference值已经存在于表中时,您会得到此信息。或

  • “值可能不为NULL” - 当您尝试将NULL插入定义为NOT NULL的列时,会得到此值。

这两个错误都会返回SQLITE_CONSTRAINT的返回码。只有通过查看sqlite3_errmsg,您才能有效地诊断出问题的根源。

坦率地说,我假设前者是问题(你要插入的reference已经存在于表格中),但在你看sqlite3_errmsg之前,我们只是在猜测

int result;

if ((result = sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL)) != SQLITE_OK) {
    NSLog(@"%s: sqlite3_prepare error: %s (%d)", __FUNCTION__, sqlite3_errmsg(database), result);
}

if ((result = sqlite3_step(statement)) != SQLITE_DONE) {
    NSLog(@"%s: step error: %s (%d)", __FUNCTION__, sqlite3_errmsg(database), result);
}
else
    NSLog(@"success");

sqlite3_finalize(statement);

查看sqlite3_errmsg,它会准确地告诉您出了什么问题。然后,您可能希望检查要插入的值,并将其与表中已有的值以及您定义的约束(NOT NULL)进行比较。