8

Voici le logcat:IllegalArgumentException: colonne non valide

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) 

La ligne qui est associé est:

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

Quel pourrait être le problème? La base de données est créée très bien. Y a-t-il un autre code à voir?

MISE À JOUR:
Je suis très sûr que cette colonne existe. J'interroge sur la base de données avec ceci:

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

Et 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 

Ainsi, la colonne n'existe.

+0

Quelle est la ligne: 105? task = getContentResolver(). requête (uri, PROJECTION, null, null, null); – fiction

+0

Oui. Vous avez raison. –

+0

À propos de - 'Colonne non valide due_date'. Êtes-vous sûr à 100% qu'il existe une telle colonne? – fiction

Répondre

7

J'ai trouvé une solution bizarre à cela. Au String[] PROJECTION. Vous devez faire:

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

Pouvez-vous expliquer pourquoi cela fonctionne? – HEATH3N

0

Avez-vous ajouter cette colonne dans la carte de projection du fournisseur de contenu, par rapport à la table avec cette colonne? J'espère que ça aide.

17

La colonne existe sans aucun doute dans votre base de données, mais si vous n'avez pas ajouté la colonne à une chose appelée projection map, vous obtiendrez l'erreur "colonne non valide" que vous voyez. Vous pouvez ajouter la carte de projection via un objet générateur de requêtes, comme ceci:

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

Pour comprendre ce qui se passe, regardez dans la source de la classe SQLiteQueryBuilder, et vous verrez les éléments suivants:

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

Fondamentalement, il vérifie les colonnes que vous avez demandées dans votre projection par rapport à une liste de colonnes "autorisées", et vous pouvez voir que si la carte ne contient pas la colonne de votre projection, elle lèvera une exception IllegalArgumentException, comme vous l'avez vu. (J'imagine que cette vérification contre la carte est une fonction de sécurité pour empêcher les attaques SQL des utilisateurs abusant de votre fournisseur de contenu, mais c'est juste une supposition.)

Notez également que si vous définissez des cartes de projection "strictes" dans votre requête constructeur:

qb.setStrictProjectionMap(true); 

Alors dans ce cas, il vous attend de connaître le nom exact de la colonne ... Si vous ne définissez pas, il vérifie la « AS » alias de colonne - Je pense que cela explique la " correction bizarre "vous avez découvert.

Espérons que cela aide.

+0

tns @DMH bon travail! – FlipNovid

Questions connexes