请求索引 0 时出现错误,android Sqlite 中大小为 0 时想要 select

Getting error Index 0 requested, with a size of 0 in android Sqlite when want to select

我有一个使用 SQLite 数据库的 android 应用程序。我有一个 CardView 并且有名称、成本和描述等数据。我的 CardView 有一个选项菜单来输入数据并更新它。单击选项菜单时,它将转到另一个 activity。在 activity 中,它有一个将在 CardView 中显示相同名称的 TextView。

这是我的数据库代码

 public ModelPemesanan getnamap(int selectionn){
    SQLiteDatabase db = this.getReadableDatabase();
    String cb = "SELECT * FROM " + TABLE_PEMESANAN + " WHERE " + KEY_ID_PEMESANAN + "= '" + selectionn + "'";
    Cursor cursor = db.rawQuery(cb, null);
    if (cursor != null)
        cursor.moveToFirst();

    ModelPemesanan modelPemesanan = new ModelPemesanan();
    modelPemesanan.set_namap(cursor.getString(1));
    modelPemesanan.set_lapak(cursor.getString(2));
    modelPemesanan.set_desk(cursor.getString(3));
    modelPemesanan.set_lapak(cursor.getString(4));
    modelPemesanan.set_total(Integer.parseInt(cursor.getString(6)));
    modelPemesanan.set_resi(cursor.getString(7));

    db.close();
    return modelPemesanan;
}

在我用来输入数据的class中

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_resi);

    init();

    simpan.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            modelPemesanan.set_namap(nama.getText().toString());
            modelPemesanan.set_resi(nores.getText().toString());
            db.updateresi(modelPemesanan);
        }
    });

}

private void init() {
    pilih = getIntent().getIntExtra("id_pemesanan", 0);
    db = new Database(this);
    modelPemesanan = db.getnamap(pilih);

    judul = (TextView) findViewById(R.id.tvmasukkan);
    nama = (TextView) findViewById(R.id.tvnamapembeli);
    nores = (EditText) findViewById(R.id.etnoresi);
    simpan = (Button) findViewById(R.id.btsimpannoresi);
    lapak = (TextView) findViewById(R.id.tvnamalapak);


    nama.setText(modelPemesanan.get_namap());
}

在我的适配器 class 中,我使用 intent 来传递索引值。

 holder.pop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            PopupMenu popup = new PopupMenu(context, holder.pop);
            popup.inflate(R.menu.menu_list);
            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    db = new Database(context);
                    final int selectionn = listpemesanan.get(position).get_idp();
                    switch (item.getItemId()){
                        case R.id.input:
                            Intent i = new Intent(v.getContext(), ResiAct.class);
                            i.putExtra("id_pemesanan", selectionn);
                            context.startActivity(i);
                            break;

我在数据库中使用了 select 查询。这是我的 logcat

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.asus.daringku/com.example.asus.daringku.ResiAct}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2345)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2405)
    at android.app.ActivityThread.access0(ActivityThread.java:155)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1323)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5376)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
    Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
    at android.database.AbstractCursor.checkPosition(AbstractCursor.java:426)
    at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
    at com.example.asus.daringku.Database.Database.getnamap(Database.java:279)
    at com.example.asus.daringku.ResiAct.init(ResiAct.java:44)
    at com.example.asus.daringku.ResiAct.onCreate(ResiAct.java:28)
    at android.app.Activity.performCreate(Activity.java:6021)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2405) 
    at android.app.ActivityThread.access0(ActivityThread.java:155) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1323) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:135) 
    at android.app.ActivityThread.main(ActivityThread.java:5376) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)

这是我的 XML

 <TextView
    android:id="@+id/tvmasukkan"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Masukkan Nomor Resi untuk : "
    android:textSize="20sp"
    android:padding="10dp"/>
<TextView
    android:id="@+id/tvnamapembeli"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="17sp"
    android:padding="10dp"
    android:text="NAMA"
    android:layout_below="@id/tvmasukkan"
    />
<TextView
    android:id="@+id/tvnamalapak"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tvnamapembeli"
    android:padding="10dp"
    android:textSize="17sp"
    android:text="NAMA LAPAK"
    />
<EditText
    android:id="@+id/etnoresi"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:hint="Masukkan Nomor Resi"
    android:padding="10dp"
    android:layout_below="@id/tvnamalapak"/>
<Button
    android:id="@+id/btsimpannoresi"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/etnoresi"
    android:layout_centerHorizontal="true"
    android:padding="10dp"
    android:text="simpan"/>

请帮忙!谢谢。

大小为 0 表示没有可从中提取数据的提取行。

当没有行时,您不应该尝试从 Cursor 中提取数据(您会遇到这样的异常),因此您应该检查是否有来自在尝试从游标中提取数据之前可以提取哪些数据。

您的代码正在检查从 rawQuery 方法 return 编辑的游标,以查看它是否为 null,可能是为了避免检查一个空的 Cursor。检查 null 作为从 rawQuery 方法 returned 的游标是无用的,即使它是空的,也不会为空(它的计数将为 0,如果没有行)。

您可以使用 Cursor getCount() 方法检查行数,看看是否有 0 行。但是,光标 moveTo????方法,例如 moveToFirst 方法,return true 如果可以移动,否则 false。当您使用 moveToFirst 方法时,您只需要检查结果以查看是否进行了移动,而不是检查行数。

因此你可以使用 :-

public ModelPemesanan getnamap(int selectionn){
    SQLiteDatabase db = this.getReadableDatabase();
    String cb = "SELECT * FROM " + TABLE_PEMESANAN + " WHERE " + KEY_ID_PEMESANAN + "= '" + selectionn + "'";
    Cursor cursor = db.rawQuery(cb, null);
    ModelPemesanan modelPemesanan = new ModelPemesanan(); //<<<<<<<< MOVED HERE
    if (cursor.moveToFirst() {

        modelPemesanan.set_namap(cursor.getString(1));
        modelPemesanan.set_lapak(cursor.getString(2));
        modelPemesanan.set_desk(cursor.getString(3));
        modelPemesanan.set_lapak(cursor.getString(4));
        modelPemesanan.set_total(Integer.parseInt(cursor.getString(6)));
        modelPemesanan.set_resi(cursor.getString(7));
    }
    cursor.close() //<<<<<<<< YOU SHOULD ALWAYS CLOSE CURSORS WHEN DONE WITH THEM
    db.close();
    return modelPemesanan;
}
  • 注意 如果没有行 returned 则 returned ModelPemesanan 将保持原样。因此,您可能应该检查它以确定是否已设置任何数据。

然而,better/recommended 方法和 android 是使用参数传递参数(防止 SQL 注入)以及 SQLiteDatabase 便捷方法(构建适当的底层 SQL) 何时可以使用。

所以推荐如下:-

public ModelPemesanan getnamap(int selectionn){
    SQLiteDatabase db = this.getReadableDatabase();
    String whereclause = KEY_ID_PEMESANAN + "=?";
    String[] whereargs = new String[]{String.valueOf(selectionn)};
    Cursor cursor = db.query(
        TABLE_PEMESANAN,
        null, //<<<< null = all columns, else String[] of columns to extract
        whereclause, //<<<< WHERE clause less WHERE keyword with ? for arguments (as per whereargs 1 for 1)
        whereargs, // <<<< arguments to replace ? placeholder on 1 for 1 basis
        null, // <<<< GROUP BY clause less GROUP BY keywords (null for no clause)
        null, // <<<< HAVING clause less HAVING keyword (null for no clause)
        null // <<<< ORDER BY clause less ORDER BY keywords (null for no clause)
    );
    ModelPemesanan modelPemesanan = new ModelPemesanan(); //<<<<<<<< MOVED HERE
    if (cursor.moveToFirst() {

        modelPemesanan.set_namap(cursor.getString(1));
        modelPemesanan.set_lapak(cursor.getString(2));
        modelPemesanan.set_desk(cursor.getString(3));
        modelPemesanan.set_lapak(cursor.getString(4));
        modelPemesanan.set_total(Integer.parseInt(cursor.getString(6)));
        modelPemesanan.set_resi(cursor.getString(7));
    }
    cursor.close() //<<<<<<<< YOU SHOULD ALWAYS CLOSE CURSORS WHEN DONE WITH THEM
    db.close();
    return modelPemesanan;
}

您的根本问题可能是传递给该方法的值,即 selectionn 不是现有的 id,因此您没有提取任何行。所以您可能需要确定为什么这个值不匹配任何行。