【问题标题】:Android SQLiteException: bind or column index out of range problemAndroid SQLiteException:绑定或列索引超出范围问题
【发布时间】:2015-08-10 21:42:45
【问题描述】:

在 android 中我使用以下语句。

model = dataHelper.rawQuery("SELECT _id, engword, lower(engword) as letter FROM word WHERE letter >= 'a' AND letter < '{' AND engword LIKE '%" + filterText + "%'", new String[ {"_id","engword", "lower(engword) as letter"});

它正在抛出android.database.sqlite.SQLiteException: bind or column index out of range: handle 0x132330

我的代码有什么问题?

【问题讨论】:

    标签: android sqlite


    【解决方案1】:

    正确的说法是:

    model = dataHelper.rawQuery("
        SELECT _id, engword, lower(engword) as letter
        FROM word W
        HERE letter >= 'a'
        AND letter < '{'
        AND engword LIKE ? ORDER BY engword ASC
        ",
        new String[] {"%" + filterText + "%"}
    );
    

    【讨论】:

      【解决方案2】:

      您提供了 3 个参数,但您的查询中没有 ?。将 null 而不是字符串数组作为rawQuery 的第二个参数传递给rawQuery,或者将您选择的字符串中的_idengwordlower(engword) as letter 替换为?

      1)

      model = dataHelper.rawQuery("SELECT ?, ?, ? FROM word WHERE letter >= 'a' AND letter < '{' AND engword LIKE '%" + filterText + "%'",new String[] {"_id","engword", "lower(engword) as letter"});
      

      2)

      model = dataHelper.rawQuery("SELECT _id, engword, lower(engword) as letter FROM word WHERE letter >= 'a' AND letter < '{' AND engword LIKE '%" + filterText + "%'", null);
      

      编辑: 正如@Ewoks 指出的那样,选项(1)是不正确的,因为准备好的语句只能在 WHERE 子句中获取参数(?s)。

      【讨论】:

      • 语句应该是什么:model = dataHelper.rawQuery("SELECT ?, ? FROM word WHERE lower(engword) >= 'a' AND lower(engword)
      • 欢迎您。我今天花了很大一部分时间尝试使参数和 rawQuery 工作。这不是我的问题,但它会帮助某人;)干杯
      【解决方案3】:

      如果有人像我一样尝试(但失败)与getContentResolver().query 一起工作,我是如何管理它的:

      *感谢 @CL 和 @Wolfram Rittmeyer 的 cmets 更新,因为他们说这与 rawQuery *

      正确方法:

        public static String SELECTION_LIKE_EMP_NAME = Columns.EMPLOYEE_NAME
                  + " like ?";            
      
        Cursor c = context.getContentResolver().query(contentUri,
                      PROJECTION, SELECTION_LIKE_EMP_NAME, new String[] { "%" + query + "%" }, null);
      

      之前对 SQL 注入攻击开放的答案:

      public static String SELECTION_LIKE_EMP_NAME = Columns.EMPLOYEE_NAME
                  + " like '%?%'";
      
      String selection = SELECTION_LIKE_EMP_NAME.replace("?", query);
      
      Cursor c = context.getContentResolver().query(contentUri,
                  PROJECTION, selection, null, null);
      

      【讨论】:

      • 这是错误的,会引入格式问题并允许SQL injection attacks。您应该将sensorId 放入selectionArgs
      • 嗯,好的点 Re:SQLInjection,但其他答案也是如此(不是辩护,只是说)。当您说“错误”时,我不清楚您的意思是什么?它确实有效。我很想使用 selectionArgs,但它不起作用。
      • 第一个答案(这个问题的所有者标记为“答案”的答案)没有SQL注入问题,因为它使用的是selectionArgs。 Android 会小心地将它们转换为安全的字符串。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 2016-03-16
      • 1970-01-01
      相关资源
      最近更新 更多