Как изменить курсор, который вызывает исключение IllegalArgumentException: столбец ‘_id’ не существует

#java #android #sqlite

#java #Android #sqlite

Вопрос:

Когда я запускаю TestSelected activity logcat показывает:

 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sjkdev.androidsqlite/com.sjkdev.androidsqlite.TestSelected}: java.lang.IllegalArgumentException: column '_id' does not exist
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2793)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2864)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6523)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:831)
     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.sjkdev.androidsqlite.TestSelected.onCreate(TestSelected.java:37)
        at android.app.Activity.performCreate(Activity.java:6910)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2746)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2864) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:156) 
        at android.app.ActivityThread.main(ActivityThread.java:6523) 
        at java.lang.reflect.Method.invoke(Native Method) 
  

У меня есть столбец с именем «_id», как вы можете видеть в моем коде:

SQLiteAdapter.java

 public class SQLiteAdapter {

    public static final String MYDATABASE_NAME = "MY_DATABASE";
    public static final String MYDATABASE_TABLE = "MY_TABLE";
    public static final int MYDATABASE_VERSION = 1;
    public static final String _id = "_id";
    public static final String KEY_NAME = "Name";
    public static final String KEY_PRICE = "Price";
    public static final String KEY_QUANTITY = "Quantity";
    public static final String KEY_MU = "MU";
    public static final String KEY_PDATE = "PDate";
    public static final String KEY_SHOP = "Shop";

    //create table MY_DATABASE (ID integer primary key, Content text not null);
    private static final String SCRIPT_CREATE_DATABASE =
            "create table "   MYDATABASE_TABLE   " ("
                      _id   " integer primary key autoincrement, "
                      KEY_NAME   " text, "
                      KEY_PRICE   " text,"
                      KEY_QUANTITY   " text, "
                      KEY_MU   " text, "
                      KEY_PDATE   " text, "
                      KEY_SHOP   " text);";

    private SQLiteHelper sqLiteHelper;
    private SQLiteDatabase sqLiteDatabase;

    private Context context;

    public SQLiteAdapter(Context c){
        context = c;
    }

    public SQLiteAdapter openToRead() {
        sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null, MYDATABASE_VERSION);
        sqLiteDatabase = sqLiteHelper.getReadableDatabase();
        return this;
    }

    public void close(){
        sqLiteHelper.close();
    }


    public Cursor makeSelected(){
        String[] selectedColumn = new String[]{KEY_NAME, KEY_PRICE};
        Cursor selectedCursor = sqLiteDatabase.query(MYDATABASE_TABLE, selectedColumn,
                null, null, null, null, null);
        return selectedCursor;
    }

    public class SQLiteHelper extends SQLiteOpenHelper {

        public SQLiteHelper(Context context, String name,
                            CursorFactory factory, int version) {
            super(context, name, factory, version);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // TODO Auto-generated method stub
            db.execSQL(SCRIPT_CREATE_DATABASE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // TODO Auto-generated method stub

        }

    }

}
  

TestSelected.java

 public class TestSelected extends AppCompatActivity {

    private SQLiteAdapter mySQLiteAdapter;
    ListView selectedList;
    SimpleCursorAdapter selectedCursorAdapter;
    Cursor selectedCursor;

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

        selectedList = (ListView) findViewById(R.id.list_selected);

        mySQLiteAdapter = new SQLiteAdapter(this);
        mySQLiteAdapter.openToRead();
        selectedCursor = mySQLiteAdapter.makeSelected();



        selectedCursorAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1,
                selectedCursor,
                new String[]{"KEY_PRICE"},
                new int[]{android.R.id.text1}, 0);
        selectedList.setAdapter(selectedCursorAdapter);

    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        mySQLiteAdapter.close();
    }

    private void updateList(){
        selectedCursor.requery();
    }
}
  

Я думаю, что я допустил ошибку в

  1. общедоступный SQLiteAdapter openToRead() { … } ИЛИ / И

  2. общедоступный курсор makeSelected(){ … } ИЛИ / И

  3. открытие и создание курсора в TestSelected.java

Ответ №1:

В результирующем наборе, к которому Cursor вы переходите, CursorAdapter должен быть _id столбец. Вы можете добавить его здесь:

 public Cursor makeSelected(){
    String[] selectedColumn = new String[]{_id, KEY_NAME, KEY_PRICE};
    //-------------------------------------^^^
  

Продолжение:

теперь logcat показывает: > столбец ‘KEY_PRICE’ не существует

Имя столбца находится в константе, KEY_PRICE а не в строковом литерале "KEY_PRICE" . Изменить

 new String[]{"KEY_PRICE"},
  

Для

 new String[]{KEY_PRICE},
  

Комментарии:

1. Спасибо за быстрый ответ. Я добавил его, теперь logcat показывает: > столбец ‘KEY_PRICE’ не существует

2. Я изменил его и импортировал следующим образом: import static com….SQLiteAdapter. KEY_PRICE; . Теперь это работает как шарм. Большое вам спасибо, от вас были действительно быстрые ответы 🙂 . Хорошего дня.

3. Или без импорта SQLiteAdapter. KEY_PRICE, я могу изменить новую строку []{KEY_PRICE} на {«Price»} (потому что KEY_PRICE = «Цена»).