2012-07-12 68 views
1

所以我一直在設置一個SQL Databse的單詞,就我從調試日誌中可以看出的情況而言,它實際上確實可以加載和設置。但是,當我試圖查詢它時,無論它是處於設置過程還是已經完成,我的程序因爲異常而被強制關閉。日誌的調查顯示這一點:Android中神祕的SQLiteBindOrColumnOutOfRangeException。

07-12 13:47:02.000: W/dalvikvm(5247): threadid=1: thread exiting with uncaught exception 
(group=0x40a401f8) 
... 
07-12 13:47:02.010: E/AndroidRuntime(5247): Caused by: 
android.database.sqlite.SQLiteBindOrColumnIndexOutOfRangeException: bind or column index out of 
range: handle 0x14a6548 
... 
07-12 14:41:36.250: E/AndroidRuntime(6326):  at com.example.wordsearchandroid.WordListProvider.query(WordListProvider.java:70) 

在Android API一個搜索SQLiteBindOrColumnIndexOutOfRangeException的揭示了一個非常簡樸的...頁面(http://developer.android.com/reference/android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException .html)沒有提到「句柄」指的是什麼。

不幸的是,據我所知,我的查詢中沒有任何東西指的是不存在的列。這是我的ContentProvider我的查詢方法:

public class WordListProvider extends ContentProvider { 
private WordListOpenHelper listOpenHelper; 
.... 

public static final String ID = "_ID"; 
public static final String WORD = "WORD"; 
public static final String LENGTH = "LENGTH"; 
... 

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 
    SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder(); 
    qBuilder.setTables(DB_NAME); 
    Cursor c; 

    switch(matcher.match(uri)) { 

     case SEARCH_WORD_LIST: 

      Log.d("WORDLISTPROVIDER", "Entered Search"); 
      c = qBuilder.query(listOpenHelper.getReadableDatabase(), projection, null, 
        selectionArgs, null, null, null); 
      Log.d("WORDLISTPROVIDER", "Query Completed"); 
      if (c == null) 
       return null; 
      c.setNotificationUri(getContext().getContentResolver(), uri); 
      break; 

      default: 
       Log.d("WORDLISTPROVIDER", "Default Entered"); 
       throw new IllegalArgumentException("Unknown URI " + uri); 

    } 
    Log.d("WORDLISTPROVIDER", "Exited Search"); 
    return c; 
} 

^唯一的例外發生在該行

c = qBuilder.query(listOpenHelper.getReadableDatabase(), projection, null, 
        selectionArgs, null, null, null); 

供參考,在這裏是如何爲這個特定呼叫投影和selectionArgs兩個字符串設定:

String[] proj = { 
      WordListProvider.ID, 
      WordListProvider.WORD 
    }; 
String[] selectionArgs = {""}; 

這裏是我的數據庫的構建器,它是WordListProvider中的內部類:

private static class WordListOpenHelper extends SQLiteOpenHelper { 

    private SQLiteDatabase wordDb; 
    private Context helperContext; 

    private static final String WORD_LIST_CREATE = "CREATE TABLE "+ DB_NAME + 
      " (" + 
      ID + " INTEGER PRIMARY KEY, " + 
      WORD + " TEXT, " + 
      LENGTH + " INTEGER " + 
      ");"; 

    WordListOpenHelper(Context context) { 
     super(context, "wordlist", null, 1); 
     helperContext = context; 
     Log.d("OPENHELPER", "Constructed"); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     Log.d("OPENHELPER", "Creating"); 
     wordDb = db; 
     Log.d("OPENHELPER", "DB set"); 
     wordDb.execSQL(WORD_LIST_CREATE); 
     Log.d("OPENHELPER", "SQL Execed"); 
     loadWordList(); 
    } 

    private void loadWordList() { 
     new Thread(new Runnable() { 
      public void run() { 
       try { 
        loadWords(); 
       } catch (IOException e) { 
        Log.d("OPENHELPER", "Exception Caught"); 
        throw new RuntimeException(e); 
       } 
      } 
     }).start(); 
    } 

    private void loadWords() throws IOException { 
     ... 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     ... 
    } 



} 

loadWords最終會完成,但是我得到異常,無論表是否已完成加載(有時表不會完成加載,我會得到異常,程序將退出。表格將完成加載)。此外,我的列名是一致的,至少它們在表面上似乎是 - 如果我向查詢傳遞投影的null(即返回所有行),甚至會發生異常;任何人有任何可能導致異常的想法,或者處理意味着什麼?

回答

4

請檢查您的提供商這一行:

c = qBuilder.query(listOpenHelper.getReadableDatabase(), projection, null, 
        selectionArgs, null, null, null); 

您使用selectionArgs兩個沒有選擇參數。如果您傳遞不爲null selectionArgs查詢將失敗,因爲沒有可以將選擇參數綁定到的位置。

此行應該是這樣的:

c = qBuilder.query(listOpenHelper.getReadableDatabase(), projection, selection, 
         selectionArgs, null, null, null); 

不能使用selectionArgs兩個沒有選擇,所以試圖通過null代替

String[] selectionArgs = {""}; 
+0

是的,做它。 API參考文件沒有提到這一點,而API指南則完全相反。謝謝。 – user1521682 2012-07-13 19:02:35

+0

完成。如何將問題標記爲已回答? – user1521682 2012-07-16 15:16:10

+0

謝謝,我不知道我是否理解你的問題,但你可以閱讀關於接受問題[這裏](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-工作) – Leszek 2012-07-16 20:57:55