我有一个 SQLite 表:
CREATE TABLE regions (_id INTEGER PRIMARY KEY, name TEXT, UNIQUE(name));
还有一些安卓代码:
Validate.notBlank(region);
ContentValues cv = new ContentValues();
cv.put(Columns.REGION_NAME, region);
long regionId =
db.insertWithOnConflict("regions", null, cv, SQLiteDatabase.CONFLICT_IGNORE);
Validate.isTrue(regionId > -1,
"INSERT ON CONFLICT IGNORE returned -1 for region name '%s'", region);
在重复行上 insertWithOnConflict() 返回 -1,表示错误,然后Validate抛出:
INSERT ON CONFLICT IGNORE returned -1 for region name 'Overseas'
SQLite ON CONFLICT 文档(重点是我的)指出:
当发生适用的约束违例时,IGNORE 解析算法会跳过包含约束违例的一行并继续处理 SQL 语句的后续行,就好像没有出错一样。包含违反约束的行之前和之后的其他行被正常插入或更新。使用 IGNORE 冲突解决算法时不返回错误。
Android insertWithOnConflict () 文档指出:
如果输入参数 'conflictAlgorithm' = CONFLICT_IGNORE,则返回新插入行的行 ID 或现有行的主键,如果有任何错误,则返回 -1
CONFLICT_REPLACE 不是一个选项,因为替换行将更改它们的主键,而不仅仅是返回现有键:
sqlite> INSERT INTO regions (name) VALUES ("Southern");
sqlite> INSERT INTO regions (name) VALUES ("Overseas");
sqlite> SELECT * FROM regions;
1|Southern
2|Overseas
sqlite> INSERT OR REPLACE INTO regions (name) VALUES ("Overseas");
sqlite> SELECT * FROM regions;
1|Southern
3|Overseas
sqlite> INSERT OR REPLACE INTO regions (name) VALUES ("Overseas");
sqlite> SELECT * FROM regions;
1|Southern
4|Overseas
我认为 insertWithOnConflict() 应该在重复行上返回我重复行的主键(_id 列)——所以我不应该收到这个插入的错误。为什么 insertWithOnConflict() 会抛出错误?我需要调用什么函数才能始终获得有效的行 ID?