java IllegalArgumentException:无效的列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4702206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 07:35:48  来源:igfitidea点击:

IllegalArgumentException: Invalid column

javaandroidsqliteandroid-contentproviderillegalargumentexception

提问by Mohit Deshpande

Here is the logcat:

这是日志猫:

01-15 16:06:03.622: ERROR/AndroidRuntime(22300): Uncaught handler: thread main exiting due to uncaught exception
01-15 16:06:03.657: ERROR/AndroidRuntime(22300): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mohit.geo2do/com.mohit.geo2do.activities.TaskEdit}: java.lang.IllegalArgumentException: Invalid column due_date
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread.access00(ActivityThread.java:119)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.os.Looper.loop(Looper.java:123)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread.main(ActivityThread.java:4363)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at java.lang.reflect.Method.invokeNative(Native Method)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at java.lang.reflect.Method.invoke(Method.java:521)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at dalvik.system.NativeStart.main(Native Method)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300): Caused by: java.lang.IllegalArgumentException: Invalid column due_date
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.database.sqlite.SQLiteQueryBuilder.computeProjection(SQLiteQueryBuilder.java:508)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.database.sqlite.SQLiteQueryBuilder.buildQuery(SQLiteQueryBuilder.java:356)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:309)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:266)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at com.mohit.geo2do.provider.TasksProvider.query(TasksProvider.java:174)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.content.ContentProvider$Transport.query(ContentProvider.java:130)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.content.ContentResolver.query(ContentResolver.java:202)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at com.mohit.geo2do.activities.TaskEdit.onCreate(TaskEdit.java:105)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)

The line that's associated with it is:

与之相关的行是:

private Cursor task;
private Uri uri;
private String[] PROJECTION { 
    Tasks._ID, Tasks.TITLE, Tasks.COMPLETED, Tasks.DUE_DATE, Tasks.IMPORTANCE, Tasks.NOTES
};
...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.edit_task);
    ...
    uri = getIntent().getData();
    task = getContentResolver().query(uri, PROJECTION, null, null, null);
} 
...

What could be the problem? The database is created just fine. Is there any other code you'd need to see?

可能是什么问题呢?数据库创建得很好。您还需要查看其他代码吗?

UPDATE:
I am VERY sure this column exists. I queried the database with this:

更新:
我非常确定此列存在。我用这个查询数据库:

Cursor c = db.rawQuery("SELECT * FROM tasks LIMIT 1", null);
for (int i = 0; i < c.getColumnNames().length; i++) {
    Log.v(TAG, c.getColumnNames()[i]);
}

And in LogCat:

在 LogCat 中:

01-15 16:52:07.857: VERBOSE/TasksProvider(24325): Creating database...
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): _id
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): title
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): completed
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): due_date
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): notes
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): importance

So the column DOES exist.

所以该列确实存在。

采纳答案by Mohit Deshpande

I found a weird fix to this. In String[] PROJECTION. You have to do:

我找到了一个奇怪的解决方法。在String[] PROJECTION. 你必须做:

private String[] PROJECTION { 
    Tasks._ID, 
    Tasks.TITLE, 
    Tasks.COMPLETED,
    Tasks.DUE_DATE + " as " + Tasks.DUE_DATE, 
    Tasks.IMPORTANCE + " as " + Tasks.DUE_DATE, 
    Tasks.NOTES + " as " + Tasks.NOTES
};

回答by DMH

The column undoubtedly does exist in your database, but if you haven't added the column to a thing called the projection map, you'll get the "invalid column" error you're seeing. You can add the projection map via a query builder object, like this:

毫无疑问,该列确实存在于您的数据库中,但是如果您尚未将该列添加到称为投影映射的内容中,您将看到您看到的“无效列”错误。您可以通过查询构建器对象添加投影图,如下所示:

// The projection map is a hashmap of strings
HashMap<String, String> MyProjectionMap;
MyProjectionMap = new HashMap<String, String>();

// Add column mappings to the projection map
MyProjectionMap.put(Tasks._ID, Tasks._ID);
MyProjectionMap.put(Tasks.TITLE, Tasks.TITLE);
[...]

SQLiteQueryBuilder qb;
qb.setTables("tasks");
qb.setProjectionMap(MyProjectionMap)

// Then do your query
Cursor c = qb.query(db, projection, ...)

To understand what happens, look in the source for the SQLiteQueryBuilder class, and you'll see the following:

要了解发生了什么,请查看 SQLiteQueryBuilder 类的源代码,您将看到以下内容:

private String[] computeProjection(String[] projectionIn) {
    if (projectionIn != null && projectionIn.length > 0) {
       if (mProjectionMap != null) {
          [...]
          for (int i = 0; i < length; i++) {
             String userColumn = projectionIn[i];
             String column = mProjectionMap.get(userColumn);
             [...]
             if (!mStrictProjectionMap && ( userColumn.contains(" AS ") || userColumn.contains(" as "))) {
                /* A column alias already exist */
                projection[i] = userColumn;
                continue;
             }
             throw new IllegalArgumentException("Invalid column " + projectionIn[i]);
          }
      }
[...]

Basically it's checking the columns you requested in your projection against a list of "allowed" columns, and you can see that if the map does not contain the column from your projection, it will throw an IllegalArgumentException, just as you saw. (I imagine this checking against the map is a security feature to prevent SQL-based attacks from people abusing your content provider, but that's just a guess.)

基本上它是根据“允许”列的列表检查您在投影中请求的列,您可以看到如果地图不包含投影中的列,它将抛出 IllegalArgumentException,正如您所看到的。(我认为这种对地图的检查是一项安全功能,可防止人们滥用您的内容提供者进行基于 SQL 的攻击,但这只是一种猜测。)

Note also that if you set "strict" projection maps in your query builder:

另请注意,如果您在查询构建器中设置“严格”投影图:

qb.setStrictProjectionMap(true);

Then in that case it expects you to know the exact column names... If you don't set it, it checks for the "AS" column alias -- I think that explains the "weird fix" you discovered.

那么在这种情况下,它希望您知道确切的列名...如果您不设置它,它会检查“AS”列别名——我认为这解释了您发现的“奇怪的修复”。

Hope this helps.

希望这可以帮助。

回答by Paco

Have you add this column in the content provider's projection map, relative to the table with this column? I hope this helps.

您是否在内容提供者的投影图中添加了此列,相对于具有此列的表?我希望这有帮助。