IllegalArgumentException: неверный столбец - PullRequest
8 голосов
/ 16 января 2011

Вот логкат:

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.access$2200(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)

Строка, которая связана с ним:

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

В чем может быть проблема? База данных создана просто отлично. Есть ли другой код, который вам нужно увидеть?

UPDATE:
Я ОЧЕНЬ уверен, что этот столбец существует. Я запросил базу данных с этим:

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

А в 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

Итак, столбец существует.

Ответы [ 3 ]

18 голосов
/ 22 июля 2011

Столбец, несомненно, существует в вашей базе данных, но если вы не добавили столбец к объекту, называемому карта проекции , вы получите сообщение об ошибке «неверный столбец».Вы можете добавить карту проекции через объект построителя запросов, например:

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

Чтобы понять, что происходит, найдите в источнике класс 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]);
          }
      }
[...]

По сути, он проверяет столбцы, которые вы запрашивали в своей проекции, по списку «разрешенных» столбцов, и вы можете видеть, что если карта не содержит столбец из вашей проекции, она выдаст исключение IllegalArgumentException, так же, как выувидел.(Я полагаю, что эта проверка по карте является функцией безопасности для предотвращения атак на основе SQL со стороны людей, злоупотребляющих вашим поставщиком контента, но это только предположение.)

Обратите внимание, что если вы устанавливаете "строгие" проекционные карты вВаш построитель запросов:

qb.setStrictProjectionMap(true);

Тогда в этом случае он ожидает, что вы будете знать точные имена столбцов ... Если вы не установите его, он проверяет псевдоним столбца "AS" - я думаю,это объясняет «странное исправление», которое вы обнаружили.

Надеюсь, это поможет.

8 голосов
/ 16 января 2011

Я нашел странное решение этой проблемы.В 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
};
0 голосов
/ 10 февраля 2011

Вы добавили этот столбец в карту проекции поставщика контента относительно таблицы с этим столбцом?Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...