在ICS中忽略Android sqlite ON CONFLICT IGNORE

时间:2012-07-04 12:13:00

标签: android sqlite

我有一个简单的地址表,其中包含以下create语句:

"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()metod返回-1而不是现有行的id。

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

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

1 个答案:

答案 0 :(得分: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(除了巧合)。