IllegalArgumentException:無効な列
-
11-10-2019 - |
質問
これがログキャットです:
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);
}
...
何が問題なのでしょうか?データベースは正常に作成されています。他に見る必要があるコードはありますか?
アップデート:
このコラムが存在すると確信しています。これでデータベースを尋ねました。
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
したがって、列が存在します。
解決 2
私はこれに奇妙な修正を見つけました。の 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
};
他のヒント
列は間違いなくデータベースに存在しますが、列を「 投影マップ, 、「無効な列」エラーが表示されます。このようなクエリビルダーオブジェクトを介して投影マップを追加できます。
// 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]);
}
}
[...]
基本的に、「許可された」列のリストに対する予測で要求した列をチェックしています。マップに投影から列が含まれていない場合、見たように違法なメディメンツェセプトが投げられることがわかります。 (このマップに対するこのチェックは、SQLベースの攻撃がコンテンツプロバイダーを乱用することを防ぐためのセキュリティ機能であると思いますが、それは単なる推測です。)
また、クエリビルダーに「厳格な」投影マップを設定した場合にも注意してください。
qb.setStrictProjectionMap(true);
その場合、それはあなたが正確な列名を知ることを期待します...あなたがそれを設定しない場合、それはあなたが発見した「奇妙な修正」を説明する「as」列エイリアスをチェックします。
お役に立てれば。
この列のテーブルに比べて、コンテンツプロバイダーの投影マップにこの列を追加しましたか?これが役立つことを願っています。