【问题标题】:column '_id' PRIMARY KEY SimpleCursorAdapter列“_id”主键 SimpleCursorAdapter
【发布时间】:2018-04-28 16:07:31
【问题描述】:

作为项目的一部分,我正在制作跟踪用户在健身房锻炼的 Android 应用。通过各种组、重量和次数的锻炼和练习。

我希望用户命名他们的锻炼然后被带到添加锻炼活动的地方,当他们添加锻炼时,它会填充列表视图。然后我计划添加一个完成按钮并使用选择练习保存锻炼。因为这将是一对多的关系。

下面的代码是我拥有的数据库助手以及查看锻炼和练习的活动。但是 SimpleCursorAdapter 给我带来了问题。

绕着圈子试图修复这个错误,谁能帮我修复它,好吗? _id 在主键中,所以我不知道出了什么问题。在我也有 AUTOINCREMENT 之前,但它也给出了错误。

日志猫如下:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.cormac.gym12m/com.example.cormac.gym12m.ViewWorkoutsActivity}: java.lang.IllegalArgumentException: column '_id' does not exist
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                  at android.app.ActivityThread.access$900(ActivityThread.java:150)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:148)
                  at android.app.ActivityThread.main(ActivityThread.java:5417)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
               Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
                  at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:333)
                  at android.widget.CursorAdapter.init(CursorAdapter.java:180)
                  at android.widget.CursorAdapter.<init>(CursorAdapter.java:157)
                  at android.widget.ResourceCursorAdapter.<init>(ResourceCursorAdapter.java:96)
                  at android.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:104)
                  at com.example.cormac.gym12m.ViewWorkoutsActivity.onCreate(ViewWorkoutsActivity.java:42)
                  at android.app.Activity.performCreate(Activity.java:6294)
                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                  at android.app.ActivityThread.access$900(ActivityThread.java:150) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:148) 
                  at android.app.ActivityThread.main(ActivityThread.java:5417) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
 I/Process: Sending signal. PID: 16275 SIG: 9
  Application terminated.

数据库助手

public class DBHelper extends SQLiteOpenHelper {

public static String DATABASE_NAME = "gym_db";
private static final int DATABASE_VERSION = 1;

public static final String TABLE_WORKOUT = "workout_table";
public static final String WORKOUT_ID = "_id";
public static final String WORKOUT_NAME = "workout_name";

public static final String TABLE_EXERCISE = "exercise_table";
public static final String EXERCISE_ID = "exercise_id";
public static final String EXERCISE_NAME = "exercise_name";
public static final String EXERCISE_SET = "exercise_set";
public static final String EXERCISE_WEIGHT = "exercise_weight";
public static final String EXERCISE_REP = "exercise_rep";

public static final String createWorkoutTable = "CREATE TABLE " + TABLE_WORKOUT + "("
        + WORKOUT_ID + " _id INTEGER PRIMARY KEY, "
        + WORKOUT_NAME + " TEXT NOT NULL " +
        ")";


public static final String createExerciseTable = " CREATE TABLE " + TABLE_EXERCISE + "("
        + EXERCISE_ID + " _id INTEGER PRIMARY KEY, "
        + EXERCISE_NAME + " TEXT NOT NULL, "
        + EXERCISE_SET + " INTEGER NOT NULL, "
        + EXERCISE_WEIGHT + " INTEGER NOT NULL, "
        + EXERCISE_REP + " INTEGER NOT NULL, "
        + "FOREIGN KEY(" + EXERCISE_ID + ") REFERENCES " + TABLE_WORKOUT + "(id)" +
        ")";


public DBHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL(createWorkoutTable);
    db.execSQL(createExerciseTable);

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS '" + createWorkoutTable + " ' ");
    db.execSQL("DROP TABLE IF EXISTS '" + createExerciseTable + " ' ");
    onCreate(db);


}

private static void setForeignKeyConstraintEnabled(@NonNull SQLiteDatabase db){
    if (!db.isReadOnly()){
        db.execSQL("PRAGMA foreign_keys=1");
    }
}

private static void setForeignKeyConstraintDisabled(@NonNull SQLiteDatabase db){
    if (!db.isReadOnly()){
        db.execSQL("PRAGMA foreign_keys=0");
    }
}



public void addExercise(long l, String name, String set, String weight, String reps){

    SQLiteDatabase db = this.getWritableDatabase();

    //adding exercise name in exercise table
    ContentValues cv = new ContentValues();
    cv.put(EXERCISE_NAME, name);
    cv.put(EXERCISE_SET, set);
    cv.put(EXERCISE_WEIGHT,weight);
    cv.put(EXERCISE_REP,reps);
    db.insert(TABLE_EXERCISE, null, cv);

}


public long addWorkout(String name){
    SQLiteDatabase db = this.getWritableDatabase();



    //adding workout name in workout table
    ContentValues values = new ContentValues();
    values.put(WORKOUT_NAME, name);
    return this.getWritableDatabase().insert(TABLE_WORKOUT,null,values);

}

public Cursor getWorkouts(){
    return this.getWritableDatabase().query(TABLE_WORKOUT, null,null,null,null,null,null);
}

public long addExercise(String name, String set, String weight, String reps){

    SQLiteDatabase db = this.getWritableDatabase();

    //adding exercise name in exercise table
    ContentValues cv = new ContentValues();
    cv.put(EXERCISE_NAME, name);
    cv.put(EXERCISE_SET, set);
    cv.put(EXERCISE_WEIGHT,weight);
    cv.put(EXERCISE_REP,reps);
    return this.getWritableDatabase().insert(TABLE_EXERCISE,null,cv);

}

public Cursor getWorkoutExercises(long exerciseid){
    return this.getWritableDatabase().query(TABLE_EXERCISE, null,
            EXERCISE_ID+"=?",
            new String[]{Long.toString(exerciseid)},
            null,null,null);

}





public Cursor getAllWorkoutsExercises(int i){

    SQLiteDatabase db = this.getReadableDatabase();

    String SELECT_QUERY = "SELECT * FROM '" + TABLE_WORKOUT  + "'JOIN'" + TABLE_EXERCISE +  "' ON '" + EXERCISE_ID  + "' GROUP BY '" + EXERCISE_ID + "'ORDER BY'" + WORKOUT_NAME + "'";
    Cursor mCursor = db.rawQuery(SELECT_QUERY, null);

    return mCursor;
}

}

查看锻炼活动

public class ViewWorkoutsActivity extends AppCompatActivity{

ListView workoutlist;
ListView exerciselist;

Cursor workoutsCursor;
Cursor exercisesCursor;

SimpleCursorAdapter sca_workEx;
SimpleCursorAdapter sca_workouts;


DBHelper dbh = new DBHelper(this);


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_view_workouts);

    workoutlist = (ListView) findViewById(R.id.workoutlist);
    exerciselist = (ListView) findViewById(R.id.exerciselist);

    exercisesCursor = dbh.getWorkoutExercises(-1);
    workoutsCursor = dbh.getWorkouts();

    sca_workEx  = new SimpleCursorAdapter(this,
            android.R.layout.simple_list_item_1,
            exercisesCursor,
            new String[]{DBHelper.WORKOUT_NAME},
            new int[]{android.R.id.text1},0);

    sca_workouts = new SimpleCursorAdapter(this,
            android.R.layout.simple_list_item_1,
            workoutsCursor,
            new String[]{DBHelper.WORKOUT_NAME},
            new int[]{android.R.id.text1},0);


    workoutlist.setAdapter(sca_workouts);


    workoutlist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            exercisesCursor = dbh.getAllWorkoutsExercises(1);
            sca_workouts.swapCursor(exercisesCursor);

        }
    });

}

}

【问题讨论】:

    标签: java android sqlite


    【解决方案1】:
    public static final String EXERCISE_ID = "exercise_id";
            ...
            + EXERCISE_ID + " _id INTEGER PRIMARY KEY, "
    

    此表没有名为 _id 的列。它确实有一个名为exercise_id 的列,数据类型为_id INTEGER PRIMARY KEY

    【讨论】:

      【解决方案2】:

      游标适配器,例如 SimplCursorAdapter CursorAdapter 类的子类),正如您所使用的,需要一个名为 _id。它使用它为onItemClick 等方法提供id

      游标必须包含名为“_id”的列,否则此类将不会 工作。

      摘自CursorAdapter

      这就是您遇到错误的原因。

      有两个潜在的修复方法。


      第一种是使用_id作为EXCERCISE_ID列名。

      例如编码public static final String EXERCISE_ID = "_id";

      这将需要删除表,如果丢失当前数据不是问题,最简单的方法可能是删除应用程序的数据或卸载应用程序并重新运行上述更改。另一种选择是进行更改,然后增加数据库版本,例如private static final int DATABASE_VERSION = 2; 并重新运行应用程序(这将调用 DBHelper 的 onUpgrade 方法,删除表并调用 onCreate 方法)。


      第二种方法是在光标中提供 _id 列作为派生列。

      您可以通过更改getWorkoutExercises 方法来实现此目的:-

      public Cursor getWorkoutExercises(long exerciseid){
          String[] columns = new String[]{EXERCISE_ID + " AS _id","*"}
          return this.getWritableDatabase().query(TABLE_EXERCISE, columns,
                  EXERCISE_ID+"=?",
                  new String[]{Long.toString(exerciseid)},
                  null,null,null);
      
      }
      
      • 列也可以是以下之一
        • String columns = new String[]{"*",EXERCISE_ID + " AS _id"}
        • String columns = new String[]{"*","rowid AS _id"}
        • String columns = new String[]{"rowid AS _id","*"}

      我建议重命名列名会是更好的方法。

      【讨论】:

      • @user303749 如果这回答了您的问题,请勾选此作为答案。
      • 我的声望低于 15,所以它还没有投射,当我的声望上升时会再做一次
      • @user303749 您可以将问题勾选为以任何声誉回答,这是您不能做的投票(向上箭头)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-21
      • 1970-01-01
      • 1970-01-01
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多