Android的sqlLite ON IGNORE冲突在ICS忽略冲突、sqlLite、Android、ON

2023-09-06 04:02:44 作者:与昨日相同

我有一个简单的地址表具有以下create语句:

I have a simple address table with the following create statement:

"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)"

当我添加重复的记录,插入()梅托德返回-1,现有行的不是ID。

When I add duplicate records, the insert() metod returns -1 and not the id of the existing row.

现在的问题是可重复的只在4.0+。该方法将按预期在2.2和2.3.3。

The problem is reproducible only on 4.0+. The method works as expected on 2.2 and 2.3.3.

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

Has anyone faced the same issue?

推荐答案

不幸的是,Android的文件是错误的。 (因此你code实际上并没有按预期在Android上,例如,2.2和2.3之前的版本。)

Unfortunately, the Android documentation is wrong. (And thus your code does not actually work as expected on prior versions of Android, e.g., 2.2 and 2.3.)

在2.2和2.3, insertWithOnConflict()将返回SQLite的C API函数的 sqlite3_last_insert_rowid(),其文件中明确指出,失败的插入(例如,那里的冲突解决方案,如忽视的,适用)不影响返回值。因此,如果进行了连接,没有事先插入和重复插入尝试, insertWithOnConflict()将返回0。如果先插入添加一行到任何表时,方法将返回的行ID的是的插入---当然这是非常不正确的。

In 2.2 and 2.3, insertWithOnConflict() will return the value of the SQLite C API function sqlite3_last_insert_rowid(), whose documentation clearly states that failed inserts (e.g., where the ON CONFLICT resolution, like IGNORE, is applied) do not affect the return value. Thus, if no prior insert for the connection was performed and a duplicate insert is attempted, insertWithOnConflict() will return 0. If a prior insert added a row to any table, the method will return the row id of that insert---of course this is grossly incorrect.

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

In 4.0, insertWithOnConflict() will return the value of the same SQLite C API function, except returning -1 instead of 0.

这变化就是为什么你现在观察的错误。但是,如果你在2.2和2.3仔细检查结果,你会看到,行ID时返回或忽略子句行使实际上不是正确的行ID(除巧合)。

This change is why you are now observing the error. But if you check the result closely in 2.2 and 2.3, you'll see that the row ids returned when the OR IGNORE clause is exercised are not actually the correct row ids (except coincidentally).