可以依靠SQLiteConstraint让SQLite检查我吗? 有没有抓住?

我在Android中有一个SQLite数据库,我使用一个ContentProvider来处理这些操作,这些操作被保存到一个列中具有UNIQUE限定符的表中。

问题:

然而,当我向数据库中insert重复的值时,它本身不会中断我的代码,但它仍然会吐出数以千计的SQLiteConstraintException日志行,而对我的用户来说,只是感觉像是在污染日志,一些未完成的事情。 我已经尝试捕捉exception,只是为了试验,但它仍然logging。

题:

那么,我该如何沉默那些日志? 这甚至可能吗?

请阅读下面的评论以便提出问题的原因。

错误:

时间列有UNIQUE约束

 Error inserting Factor=2.0 Time=1325375465000 Extra=none android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed at android.database.sqlite.SQLiteStatement.native_execute(Native Method) at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:55) at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1549) at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1410) at mypackage.myapp.provider.DataProvider.bulkInsert(DataProvider.java:353) at android.content.ContentProvider$Transport.bulkInsert(ContentProvider.java:179) at android.content.ContentResolver.bulkInsert(ContentResolver.java:646) at mypackage.myapp.service.MyService.onHandleIntent(MyService.java:96) at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:59) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:123) at android.os.HandlerThread.run(HandlerThread.java:60) 

如果您可以自己制定或修改SQL,无论是INSERT还是最初的CREATE TABLE ,都可以使用SQLite的冲突处理扩展 。 有两个select如何做到这一点:

  • 插入时,使用INSERT OR IGNORE而不是INSERT 。 您也可以使用OR REPLACEOR ABORT或其他任何反应。
  • 在创build表格时,为UNIQUE约束指定一个ON CONFLICT IGNORE子句。 这将导致插入或更新违反约束,默默无闻。

我发现使用INSERT OR IGNORE / INSERT OR REPLACE来处理重复数据,特别是在并发环境中,非常干净。 它会在数据库中检查一次复制,并避免首先检查存在的竞争条件(如果只有一个进程/线程正在访问数据库,那么肯定不是问题)。

但是,如果重复是错误的结果(而不是重复的事件/行为,你的代码只是没有明确的重复删除),那么这可能只是隐藏了错误,而不是修复它。 然而,缺乏明确的消除歧义在我看来并不是一个错误。 所以如果修复是检查重复,请使用数据库; 如果真正的问题是它们是在第一个地方(在实际的应用程序级别,而不是数据库行级别)生成的,那么我可能会寻找这个问题。

使用SQLiteDatabase.insertOrThrow(...)

是的,你可以离开它,如你所说,你可以修复它。 在我看来,这取决于Dups是出色的还是“因为你懒惰而发生”。

我认为,在模块入口处清理数据比在事后处理数据成本要低。 但是,如何定义成本取决于你。