IllegalArgumentException: Invalid column

此生再无相见时 提交于 2019-11-29 13:30:49

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:

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.)

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.

Hope this helps.

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

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
};

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!