2011-12-31 18 views
8

我在Android中有一个SQLite数据库,并且我使用ContentProvider来处理这些操作,这些操作被持久保存到列中具有UNIQUE限定符的表中。可以依赖SQLiteConstraint并让SQLite检查我吗?有没有抓住?

问题:

然而,当我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) 
+0

我感觉,这一切意味着什么,我试图做的是从一个独特的约束重复插入恢复偷懒的办法,因此“糙米”感觉在日志中。我可能会更好地解决创建重复条目(并调用插入)的任何内容。我都很顺利。 但这引发了一个问题(对我来说):为什么我们不能安全地将工作“卸载”到约束检查器并让它无法默认日志?以防万一我们想...也许我们期望重复...所以没什么可担心的。也许我们的数据源,在我们的控制之外是有缺陷的... – davidcesarino 2011-12-31 21:36:14

+0

评论后回答:正如我所说,为了这个问题,我是懒惰的目的,因为我试图不编码检查和让SQLite关心1)安全性(并发性),2)效率(sqlite比我更好/更快?),3)实际上(更少的代码)。然而,有些东西引起了我的注意(插入行数),所以我实现了dups检查自己,除了约束。无论如何,我最终对我的关于(1)的代码非常满意。请记住,当阅读这个问题。 – davidcesarino 2012-01-02 18:55:10

+0

如果你自己没有使用android.util.Log,那么你为什么会关心向用户记录错误? – 2014-01-24 15:16:57

回答

10

如果你可以制定或自己修改SQL,无论是INSERT或初始CREATE TABLE,您可以使用SQLite的conflict handling extensions。有两个选项如何做到这一点:

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

我发现使用INSERT OR IGNORE/INSERT OR REPLACE来处理重复数据(特别是在并发环境中)非常干净的想法。它在数据库中检查一次重复 - 并避免首先检查存在的竞争条件(如果只有一个进程/线程正在访问数据库,那么肯定不是问题)。但是,如果重复项是错误的结果(而不是重复的事件/操作,您的代码只是没有明确的重复删除),那么这可能只是隐藏了错误而不是修复错误。然而,缺乏明确的解迷并不是我认为的错误。所以如果修复是检查重复,请使用数据库;如果真正的问题是它们是在第一个位置(在实际的应用程序级别,而不是数据库行级别)生成的,那么我可能会寻找这个问题。

+2

谢谢,这正是我想到的。我还注意到,如果我在表模式上使用'ON CONFLICT IGNORE',Android的'SQLiteDatabase.insert(String,String,ContentValues)'会报告插入的行...所以要小心如果你需要的话。是的,考虑到我有多个服务下载的东西,它也有避免竞争条件的好处。谢谢。 – davidcesarino 2011-12-31 23:03:46

1

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

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

+0

大部分的dups都没有,但是在触发服务下载器之前,其中一些可能会被我修复。我同意在入口点检查。然而,我还没有完成代码,而且我也是以“假设”的角度来问这个问题。 – davidcesarino 2011-12-31 23:06:32

4

使用SQLiteDatabase.insertOrThrow(...)

相关问题