SQLite查询仅对某些列崩溃-无法读取第0行第-1列 [英] SQLite query crashing only for certain column - Failed to read row 0, column -1

查看:116
本文介绍了SQLite查询仅对某些列崩溃-无法读取第0行第-1列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个SQLite方法,该方法以String []形式返回整列。它仅在单个列时崩溃。我可以替代其他列,效果很好。这是方法。

I have a SQLite method that returns an entire column in String[] form. It crashes only with a single column. I can substitute other columns and it works fine. Here is the method.

public String[] getLocationColumn(){
   ArrayList<String> arrayList = new ArrayList<>();
   String[] column = { KEY_LOCATION };
   db.beginTransaction();
   try{
       Cursor c = db.query(TABLE_TRAILS, column, null, null, null, null, null);
       if (c != null && c.getCount() != 0){
           c.moveToFirst();
           while (!c.isAfterLast()){
               arrayList.add(c.getString(c.getColumnIndex(KEY_LOCATION)));
               c.moveToNext();
           }
           c.close();
           db.setTransactionSuccessful();
       }
   }finally{
       db.endTransaction();
   }
   return arrayList.toArray(new String[arrayList.size()]);
 }

这是我得到的错误。


02-10 19:57:40.674 23786-23786 / com.xxxx.xxxx E / CursorWindow:无法从具有24个的CursorWindow读取行0,列-1行,共1列。

02-10 19:57:40.674 23786-23786/com.xxxx.xxxx E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 24 rows, 1 columns.

要重复一遍,我可以用例如KEY_NAME代替KEY_LOCATION,它可以正常工作。

To repeat, I can substitute, for example KEY_NAME instead of KEY_LOCATION and it works fine.

更新
我刚刚在模拟器上运行(而不是实际的电话,它运行良好)。似乎仅限于手机上的一列。

UPDATE I've just ran on an emulator (instead of actual phone and it works fine). It seems to limited to a single column on my phone.

这里有更多日志(@Mike建议使用dumpCursor)

Here's more of the log (with the dumpCursor as suggested by @Mike)


02-10 21:06:10.384 23480-23480 / com.xxxx I / System.out:}
02-10 21:06:10.384 23480- 23480 / com.xxxx I / System.out:1 {$​​ b $ b 02-10 21:06:10.384 23480-23480 / com.xxxx I / System.out:location =田纳西州Collegedale
02-10 21:06:10.384 23480-23480 / com.xxxx I / System.out:}
02-10 21:06:10.384 23480-23480 / com.xxxx I / System.out:2 {
02-10 21:06:10.384 23480-23480 / com.xxxx I / System.out:位置=田纳西州哈里森
02-10 21:06:10.384 23480-23480 / com.xxxx I / System.out :}
02-10 21:06:10.384 23480-23480 / com.xxxx I / System.out:<<<<<
02-10 21:06:10.384 23480-23480 / com.xxxx E / CursorWindow:无法从具有24行1列的CursorWindow读取行0,列-1。
02-10 21:06:10.384 23480-23480 / com.xxxx D / AndroidRuntime:关闭VM

02-10 21:06:10.384 23480-23480/com.xxxx I/System.out: } 02-10 21:06:10.384 23480-23480/com.xxxx I/System.out: 1 { 02-10 21:06:10.384 23480-23480/com.xxxx I/System.out: location=Collegedale, Tennessee 02-10 21:06:10.384 23480-23480/com.xxxx I/System.out: } 02-10 21:06:10.384 23480-23480/com.xxxx I/System.out: 2 { 02-10 21:06:10.384 23480-23480/com.xxxx I/System.out: location=Harrison, Tennessee 02-10 21:06:10.384 23480-23480/com.xxxx I/System.out: } 02-10 21:06:10.384 23480-23480/com.xxxx I/System.out: <<<<< 02-10 21:06:10.384 23480-23480/com.xxxx E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 24 rows, 1 columns. 02-10 21:06:10.384 23480-23480/com.xxxx D/AndroidRuntime: Shutting down VM


推荐答案

您遇到的问题是 getColumnIndex()可以(是)(区分大小写),因此可能返回-1是可接受的列名称。

The issue you have is that getColumnIndex() can be/is (see comments) case sensitive and thus may return -1 for what should be an acceptable column name.


  • 可以澄清 :-

  • Clarification of can be/is :-


ContentResolver 使用的Cursor实现会执行
浏览列名称时, equalsIgnoreCase()
SQLiteCursor的 getColumnIndex() 方法不会

The Cursor implementation that ContentResolver uses does an equalsIgnoreCase() when looking through the column names. SQLiteCursor's getColumnIndex() method does not.

Mike.M。

As researched by Mike.M.

Contentresolver getColumnIndex :-

android / platform / frameworks / base / master /./ core / java / android / database / AbstractCursor.java

SQLiteCursor getColumnIndex :-

android / platform / frameworks / base / 56a2301 /./ core / java / android / database / sqlite / SQLiteCursor.java


在这种情况下,列名已更改d从小写到大写,但数据库未更改(即光标转储显示):-

In this case the column name was changed from lower to upper case but the database was not changed (i.e. the cursor dump shows) :-

 I/System.out: location=Collegedale, Tennessee ......

虽然代码具有:-

arrayList.add(c.getString(c.getColumnIndex(KEY_LOCATION)));

OP定义为:-

private static final String KEY_LOCATION = "LOCATION"; 

因此 -1 位置不等于 LOCATION 而返回strong>。

Thus -1 is returned as location is not equal to LOCATION.

一种解决方法是,使用KEY_LOCATION作为列名来重新创建表。这可以通过重新安装该应用程序或删除该应用程序的数据来实现。 (可以选择增加版本,但取决于 onUpgrade 方法中的代码。)

One fix would be to cause the table to be recreated using KEY_LOCATION as the column name. This could be achieved by re-installing the App or deleting the App's data. (increasing the version may be an option but is dependent upon the code in the onUpgrade method.).

另一个解决方法可能是更改:-

Another get-around could be to change :-

String[] column = { KEY_LOCATION };

至:-

String[] column = { KEY_LOCATION + " AS " +  KEY_LOCATION };

实际查询将起作用,因为SQLite中的列名不区分大小写,但该列将使用失败的列名,因此 gettColumnIndex 将起作用。

the actual query would work as the column name in SQLite is case insensitive but the column would be retrieved using the failing column name thus the gettColumnIndex would then work.

可能还有其他101种解决方法。

There are probably 101 other get-arounds.

这篇关于SQLite查询仅对某些列崩溃-无法读取第0行第-1列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆