2011-12-31 63 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(...)

相關問題