私はSQLiteテーブルを持っています:
CREATE TABLE regions (_id INTEGER PRIMARY KEY, name TEXT, UNIQUE(name));
そしていくつかの Android コード:
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 解決アルゴリズムは制約違反を含む 1 行をスキップし、何も問題がなかったかのように SQL ステートメントの後続の行の処理を続行します。制約違反を含む行の前後の他の行は、正常に挿入または更新されます。IGNORE 競合解決アルゴリズムが使用されている場合、エラーは返されません。
AndroidのinsertWithOnConflict() ドキュメントには次のように記載されています。
新しく挿入された行の行 ID、または入力パラメーター 'conflictAlgorithm' = CONFLICT_IGNORE の場合は既存の行の主キー、またはエラーが発生した場合は -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 を取得するには、どの関数を呼び出す必要がありますか?