【问题标题】:Mysterious SQLiteBindOrColumnOutOfRangeException in Android.Android 中神秘的 SQLiteBindOrColumnOutOfRangeException。
【发布时间】:2012-07-12 18:47:27
【问题描述】:

所以我一直在努力建立一个 SQL 单词数据库,据我从调试日志中可以看出,它实际上确实可以正确加载和设置。但是,当我尝试查询它时,无论它是在设置过程中还是已经完成,我的程序都会因为异常而被强制关闭。对日志的调查表明:

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 会发现一个相当... spartan 页面 (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 (也就是返回所有行),甚至会发生异常;任何人对可能导致异常的原因或句柄的含义有任何想法?

【问题讨论】:

    标签: android sqlite exception


    【解决方案1】:

    请检查您的提供商中的这一行:

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

    您使用没有选择参数的 selectionArgs。如果您传递非空 selectionArgs 查询将失败,因为没有可以绑定选择参数的位置。

    这一行应该是这样的:

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

    你不能在没有选择的情况下使用 selectionArgs,所以尽量传递 null 而不是

    String[] selectionArgs = {""};
    

    【讨论】:

    • 是的,它做到了。 API 参考没有提到这一点,而 API 指南则完全相反。谢谢。
    • 谢谢,我不确定我是否理解您的评论问题,但您可以阅读关于接受问题here
    • 我指的是我已经接受了答案,但仍然有一个“未回答”标签。
    猜你喜欢
    • 1970-01-01
    • 2011-06-22
    • 2013-04-16
    • 2013-03-11
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多