8

次の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()メソッドは既存の行のIDではなく-1を返します。

この問題は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()の値を返します。このドキュメントには、失敗した挿入(たとえば、IGNOREなどのON CONFLICT解決が適用される場合)が戻り値に影響しないことが明記されています。したがって、接続に対して以前の挿入が実行されず、重複挿入が試行された場合、0が返されます。以前の挿入によってテーブルに行が追加された場合、メソッドはそのinsertWithOnConflict()挿入の行IDを返します---もちろんこれはひどく間違っています。

4.0insertWithOnConflict()では、0ではなく-1を返すことを除いて、同じSQLiteCAPI関数の値を返します。

この変更が、エラーを観察している理由です。OR IGNOREただし、2.2と2.3で結果を詳しく確認すると、句が実行されたときに返される行IDが実際には正しい行IDではないことがわかります(偶然を除く)。

于 2012-07-11T01:04:45.137 に答える