8

我有一个带有以下创建语句的简单地址表:

"CREATE TABLE " + ADDRESSES_TABLE + " (" +
                KEY_ADDRESS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                KEY_ADDRESS_COUNTRY + " TEXT, " +
                KEY_ADDRESS_CITY + " TEXT, " +
                KEY_ADDRESS_STREET + " TEXT, " +
                KEY_ADDRESS_HOUSE + " TEXT, " +
                KEY_ADDRESS_POSTAL_CODE + " TEXT," +
                "UNIQUE("+KEY_ADDRESS_COUNTRY+","+KEY_ADDRESS_CITY+","+KEY_ADDRESS_STREET+","+KEY_ADDRESS_HOUSE+","+KEY_ADDRESS_POSTAL_CODE +") ON CONFLICT IGNORE)"

当我添加重复记录时, insert() 方法返回 -1 而不是现有行的 id。

这个问题只能在 4.0+ 上重现。该方法在 2.2 和 2.3.3 上按预期工作。

有没有人遇到过同样的问题?

4

1 回答 1

9

不幸的是,Android 文档是错误的。(因此,您的代码在 Android 的早期版本(例如 2.2 和 2.3)上实际上并没有按预期工作。)

在 2.2 和 2.3 中,insertWithOnConflict()将返回 SQLite C API 函数sqlite3_last_insert_rowid()的值,其文档明确指出失败的插入(例如,应用了 ON CONFLICT 解决方案,如 IGNORE)不会影响返回值。因此,如果没有对连接执行先前的插入并且尝试重复插入,insertWithOnConflict()将返回 0。如果先前的插入向任何表添加了一行,则该方法将返回该插入的行 ID——当然这是大错特错。

在 4.0 中,insertWithOnConflict()将返回相同 SQLite C API 函数的值,除了返回 -1 而不是 0。

此更改是您现在观察错误的原因。但是,如果您仔细检查 2.2 和 2.3 中的结果,您会发现执行该OR IGNORE子句时返回的行 ID 实际上不是正确的行 ID(巧合除外)。

于 2012-07-11T01:04:45.137 回答