可以依赖SQLiteConstraint让SQLite为我做检查吗?有捕获吗?

时间:2011-12-31 21:35:22

标签: android sqlite exception-handling insert constraints

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

问题:

但是,当我insert将值复制到数据库中时,它本身并没有破坏我的代码,但它仍然会吞噬数千条SQLiteConstraintException日志行,而对我的用户来说,感觉就像污染日志,一些未经修饰的东西。我试过捕获异常只是为了实验,但它仍然记录。

问题:

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

请阅读以下评论,了解提问的理由。

错误:

时间列具有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)

3 个答案:

答案 0 :(得分:10)

如果您可以自己制定或修改SQL,无论是INSERT还是初始CREATE TABLE,都可以使用SQLite的conflict handling extensions。如何执行此操作有两种选择:

  • 插入时,请使用INSERT OR IGNORE而不是INSERT。您还可以使用OR REPLACEOR ABORT或其他任何反应。
  • 创建表时,请为ON CONFLICT IGNORE约束指定UNIQUE子句。这将导致违反约束的插入或更新无声地执行任何操作。

我发现使用INSERT OR IGNORE / INSERT OR REPLACE处理重复数据的想法非常干净,特别是在并发环境中。它会在数据库中检查一次重复 - 并避免首先检查存在的竞争条件(如果只有一个进程/线程正在访问数据库,则无可置疑)。

但是,如果重复项是错误的结果(而不是重复的事件/操作,而您的代码没有明确地重复删除),那么这可能只是隐藏错误而不是修复它。然而,在我看来,缺乏明确的去除不是一个错误。因此,如果要修复重复项,请使用数据库;如果真正的问题是它们是首先生成的(在实际应用程序级别,而不是数据库行级别),那么我可能会寻找那个问题。

答案 1 :(得分:4)

使用SQLiteDatabase.insertOrThrow(...)

答案 2 :(得分:1)

是的,你可以离开它,正如你所说,你可以解决它。在我看来,这取决于重复是否是特殊的出现或'只是发生因为你是懒惰'。

我认为在主要方面,清理模块入口处的数据要比后续处理数据要少。但是,如何定义成本取决于您。