Menghapus Baris di SQLite di Android

102

Ini mungkin pertanyaan yang bodoh, tapi saya baru mengenal SQLite dan sepertinya saya tidak bisa memahaminya. Saya memiliki 1 tabel yang memiliki kolom KEY_ROWID, KEY_NAME, KAY_LATITUDE, dan KEY_LONGITUDE. Saya ingin pengguna dapat memilih satu dan menghapusnya; Adakah yang bisa memberi saya arahan untuk memulai? Pertanyaan saya adalah pada penghapusan baris yang sebenarnya hanya diberi namanya.

Kode yang relevan:

public class BeaconDatabase {

    public static final String KEY_ROWID = "_id";
    public static final String KEY_NAME = "beacon_name";
    public static final String KEY_LATITUDE = "beacon_lat";
    public static final String KEY_LONGITUDE = "beacon_lon";

    private static final String DATABASE_NAME ="BeaconDatabase";
    private static final String DATABASE_TABLE ="beaconTable";
    private static final int DATABASE_VERSION = 1;

    private DbHelper helper;
    private final Context context;
    private SQLiteDatabase db;

    public BeaconDatabase(Context context) {
        this.context = context;
    }

    public BeaconDatabase open() {
        helper = new DbHelper(this.context);
        db = helper.getWritableDatabase();
        return this;
    }

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

    public long createEntry(String name, Double lat, Double lon) {
        ContentValues cv = new ContentValues();
        cv.put(KEY_NAME, name);
        cv.put(KEY_LATITUDE, lat);
        cv.put(KEY_LONGITUDE, lon);
        return db.insert(DATABASE_TABLE, null, cv);
    }

    public void deleteEntry(long row) {

              // Deletes a row given its rowId, but I want to be able to pass
              // in the name of the KEY_NAME and have it delete that row.
              //db.delete(DATABASE_TABLE, KEY_ROWID + "=" + row, null);
    }

    public String getData() {
        String[] columns = { KEY_ROWID, KEY_NAME, KEY_LATITUDE, KEY_LONGITUDE };
        Cursor cursor = db.query(DATABASE_TABLE, columns, null, null, null, null, null);
        String result = "";

        int iRow = cursor.getColumnIndex(KEY_ROWID);
        int iName = cursor.getColumnIndex(KEY_NAME);
        int iLat = cursor.getColumnIndex(KEY_LATITUDE);
        int iLon = cursor.getColumnIndex(KEY_LONGITUDE);

        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            result += cursor.getString(iRow) + ": " + cursor.getString(iName) + " - " + cursor.getDouble(iLat) + " latitude " + cursor.getDouble(iLon) + " longitude\n";
        }

        return result;

    }

    private static class DbHelper extends SQLiteOpenHelper {

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

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE " +  DATABASE_TABLE + " (" + 
                    KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    KEY_NAME + " TEXT NOT NULL, " +
                    KEY_LATITUDE + " DOUBLE, " +
                    KEY_LONGITUDE + " DOUBLE);"
            );
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
            onCreate(db);
        }
    }
}
roboguy12
sumber
gunakan jawaban @iDroid ... karena ini akan berhasil untuk saya. Terima kasih iDroid.

Jawaban:

183

Anda bisa mencoba seperti ini:

 //---deletes a particular title---
public boolean deleteTitle(String name) 
{
    return db.delete(DATABASE_TABLE, KEY_NAME + "=" + name, null) > 0;
}

atau

public boolean deleteTitle(String name) 
{
    return db.delete(DATABASE_TABLE, KEY_NAME + "=?", new String[]{name}) > 0;
}
Shreyash Mahajan
sumber
61
Jawaban Vijay benar karena solusi ini memungkinkan untuk melakukan injeksi SQL yang merupakan kebocoran keamanan. Misalnya: gunakan nilai argumen nama: name = "TRUE; <any SQL command>;"=> 'perintah SQL apa pun' akan dieksekusi. Tentu tidak menjadi masalah jika tidak ada GUI untuk fitur tersebut.
bdevay
@bdevay Jawaban saya adalah tentang tugas latar belakang yang kami lakukan dengan kueri. Jadi tidak terkait dengan UI. Anda hanya perlu memberikan informasi secara dinamis sehingga tidak perlu keamanan. Jika Anda mengikuti jawaban vijay dan seseorang melakukan reverse engineering maka Anda mungkin mendapat informasi tentang tabel di database dan bidang yang Anda cari. yang saya lakukan langsung di kueri sehingga tidak ada kesempatan untuk memilikinya.
Shreyash Mahajan
@iDroid Explorer: tentu saja jika tidak ada input pengguna atau kemungkinan maniplasi kueri eksternal lainnya, maka risiko keamanan tidak lebih tinggi daripada solusi lainnya. Lanjutkan di komentar berikutnya ...
bdevay
1
... Tapi saya tidak setuju dengan bagian rekayasa balik dari komentar Anda. Anda harus menentukan suatu tempat dan entah bagaimana kueri Anda yang berarti bahwa rekayasa balik selalu merupakan kemungkinan kebocoran keamanan (bahkan dalam kasus solusi Anda), terutama di Java meskipun sumbernya dikaburkan. Itu hanya dapat meningkatkan waktu peretasan lebih lama. Di sisi lain, rekomendasi Google menggunakan argumen pemilihan, silakan periksa artikel ini: tautan
bdevay
Maksud saya dengan konsep tidak memberikan nilai statis ke metode apa pun atau variabel apa pun. Itu harus maksimal dinamis. Agar lebih aman maka pemberian nilai statis. Bagaimanapun, terserah pengguna bahwa seberapa aman dia ingin membuat aplikasi mereka.
Shreyash Mahajan
157

Cobalah seperti itu semoga Anda mendapatkan solusi Anda

String table = "beaconTable";
String whereClause = "_id=?";
String[] whereArgs = new String[] { String.valueOf(row) };
db.delete(table, whereClause, whereArgs);
Vijay
sumber
58

lebih baik menggunakan whereargs juga;

db.delete("tablename","id=? and name=?",new String[]{"1","jack"});

ini seperti menggunakan perintah ini:

delete from tablename where id='1' and name ='jack'

dan menggunakan fungsi delete dengan cara seperti itu bagus karena menghapus injeksi sql.

Enakhi
sumber
2
Bisakah Anda menjelaskan lebih lanjut jawaban Anda dengan menambahkan sedikit lebih banyak deskripsi tentang solusi yang Anda berikan?
abarisone
1
Saya pikir itu layak untuk digunakan whereargs.
msysmilu
@Enkahi Apakah ini seperti pernyataan yang disiapkan di SQLite? Saya telah menggunakan id=?sintaks semacam ini dengan PHP sebelumnya dan sepertinya sangat mirip dengan itu.
GeekWithGlasses
17

Sampai saya memahami pertanyaan Anda, Anda ingin memberikan dua syarat untuk memilih baris yang akan dihapus. Untuk itu, Anda perlu melakukan:

public void deleteEntry(long row,String key_name) {

      db.delete(DATABASE_TABLE, KEY_ROWID + "=" + row + " and " + KEY_NAME + "=" + key_name, null);

      /*if you just have key_name to select a row,you can ignore passing rowid(here-row) and use:

      db.delete(DATABASE_TABLE, KEY_NAME + "=" + key_name, null);
      */  

}
Hiral Vadodaria
sumber
13

Coba kode ini

public void deleteRow(String value)
{
SQLiteDatabase db = this.getWritableDatabase();       
db.execSQL("DELETE FROM " + TABLE_NAME+ " WHERE "+COlUMN_NAME+"='"+value+"'");
db.close();
}
Harman Khera
sumber
Bagaimana saya menyebutnya ketika saya ingin menghapus? db.deleteRow ();
Phares
kita bisa menyebutnya dengan melewatkan nilai sebagai parameter yang ingin Anda hapus. Panggil sebagai db.deleteRow ("name");
Harman Khera
8

Coba kode ini ...

private static final String mname = "'USERNAME'";
public void deleteContact()
{
    db.delete(TABLE_CONTACTS, KEY_NAME + "=" + mname, null);
}
Giridharan
sumber
3

jika Anda menggunakan SQLiteDatabase maka ada metode delete

Definisi Hapus

int delete (String table, String whereClause, String[] whereArgs)

Implementasi Contoh

Sekarang kita bisa menulis metode yang disebut delete dengan argumen sebagai nama

public void delete(String value) {
    db.delete(DATABASE_TABLE, KEY_NAME + "=?", new String[]{String.valueOf(value)});
}

jika Anda ingin menghapus semua record maka cukup berikan null ke metode di atas,

public void delete() {
    db.delete(DATABASE_TABLE, null, null);
}

Sumber informasi

Jayakrishnan
sumber
Jika nilai String dilampirkan dengan kunci asing ??
Harsh Bhavsar
2

Guys ini adalah metode umum yang dapat Anda gunakan untuk semua tabel Anda, Bekerja dengan sempurna dalam kasus saya.

public void deleteRowFromTable(String tableName, String columnName, String keyValue) {
    String whereClause = columnName + "=?";
    String[] whereArgs = new String[]{String.valueOf(keyValue)};
    yourDatabase.delete(tableName, whereClause, whereArgs);
}
Naveed Ahmad
sumber
String.ValueOf (keyValue) => bisakah Anda menjelaskan baris ini?
Anis
1
Tidak perlu String.ValueOf (keyValue), karena keyValue sudah berupa string. dalam kasus lain kami menggunakan Array whereArgs ini untuk mengidentifikasi nilai nama kolom.
Naveed Ahmad
2

Untuk menghapus baris dari tabel, Anda perlu memberikan kriteria pemilihan yang mengidentifikasi baris ke delete()metode. Mekanismenya bekerja sama seperti argumen pemilihan untuk query()metode tersebut. Ini membagi spesifikasi pemilihan menjadi klausa pemilihan (di mana klausa) dan argumen pemilihan.

    SQLiteDatabase db  = this.getWritableDatabase();
     // Define 'where' part of query.
    String selection = Contract.COLUMN_COMPANY_ID + " =?  and "
                       + Contract.CLOUMN_TYPE +" =? ";
   // Specify arguments in placeholder order.
    String[] selectionArgs = { cid,mode };
    // Issue SQL statement.
    int deletedRows = db.delete(Contract.TABLE_NAME, 
                       selection, selectionArgs);
    return deletedRows;// no.of rows deleted.

Nilai kembali untuk delete()metode ini menunjukkan jumlah baris yang telah dihapus dari database.

Ram
sumber
Meskipun kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang mengapa dan / atau bagaimana kode ini menjawab pertanyaan tersebut meningkatkan nilai jangka panjangnya.
Thomas Flinkow
1

Teman-teman jika solusi di atas tidak berhasil untuk Anda, coba yang ini juga karena berhasil untuk saya.

public boolean deleteRow(String name) 
{
    return db.delete(DATABASE_TABLE, KEY_NAME + "='" + name +"' ;", null) > 0;
}
aman003
sumber
1

Bekerja dengan baik!

public void deleteNewMelk(String melkCode) {
    getWritableDatabase().delete(your_table, your_column +"=?", new String[]{melkCode});
}
Hadi Note
sumber
0

Coba yang ini:

public void deleteEntry(long rowId) {
    database.delete(DATABASE_TABLE , KEY_ROWID 
        + " = " + rowId, null);}
Nadhir Titaouine
sumber
0
public boolean deleteRow(long l) {
    String where = "ID" + "=" + l;
    return db.delete(TABLE_COUNTRY, where, null) != 0;
}
babiro
sumber
0

Anda dapat melakukan sesuatu seperti ini, membagikan cuplikan kode kerja saya

Pastikan kueri seperti ini

HAPUS DARI tableName WHERE KEY__NAME = 'parameterToMatch'

public void removeSingleFeedback(InputFeedback itemToDelete) {
            //Open the database
            SQLiteDatabase database = this.getWritableDatabase();

            //Execute sql query to remove from database
            //NOTE: When removing by String in SQL, value must be enclosed with ''
            database.execSQL("DELETE FROM " + TABLE_FEEDBACKS + " WHERE "
                    + KEY_CUSTMER_NAME + "= '" + itemToDelete.getStrCustName() + "'" +
                    " AND " + KEY_DESIGNATION + "= '" + itemToDelete.getStrCustDesignation() + "'" +
                    " AND " + KEY_EMAIL + "= '" + itemToDelete.getStrCustEmail() + "'" +
                    " AND " + KEY_CONTACT_NO + "= '" + itemToDelete.getStrCustContactNo() + "'" +
                    " AND " + KEY_MOBILE_NO + "= '" + itemToDelete.getStrCustMobile() + "'" +
                    " AND " + KEY_CLUSTER_NAME + "= '" + itemToDelete.getStrClusterName() + "'" +
                    " AND " + KEY_PRODUCT_NAME + "= '" + itemToDelete.getStrProductName() + "'" +
                    " AND " + KEY_INSTALL_VERSION + "= '" + itemToDelete.getStrInstalledVersion() + "'" +
                    " AND " + KEY_REQUIREMENTS + "= '" + itemToDelete.getStrRequirements() + "'" +
                    " AND " + KEY_CHALLENGES + "= '" + itemToDelete.getStrChallenges() + "'" +
                    " AND " + KEY_EXPANSION + "= '" + itemToDelete.getStrFutureExpansion() + "'" +
                    " AND " + KEY_COMMENTS + "= '" + itemToDelete.getStrComments() + "'"
            );

            //Close the database
            database.close();
        }
Hitesh Sahu
sumber
0

Coba kode di bawah ini-

mSQLiteDatabase = getWritableDatabase();//To delete , database should be writable.
int rowDeleted = mSQLiteDatabase.delete(TABLE_NAME,id + " =?",
                    new String[] {String.valueOf(id)});
mSQLiteDatabase.close();//This is very important once database operation is done.
if(rowDeleted != 0){
    //delete success.
} else {
    //delete failed.
}
Durgesh
sumber
0

Satu-satunya cara yang berhasil bagi saya adalah ini

fun removeCart(mCart: Cart) {
    val db = dbHelper.writableDatabase
    val deleteLineWithThisValue = mCart.f
    db.delete(cons.tableNames[3], Cart.KEY_f + "  LIKE  '%" + deleteLineWithThisValue + "%' ", null)
}


class Cart {
    var a: String? = null
    var b: String? = null
    var c: String? = null
    var d: String? = null
    var e: Int? = null
    var f: String? = null

companion object {
    // Labels Table Columns names
    const val rowIdKey = "_id"
    const val idKey = "id"
    const val KEY_a = "a"
    const val KEY_b = "b"
    const val KEY_c = "c"
    const val KEY_d = "d"
    const val KEY_e = "e"
    const val KEY_f = "f"
   }
}

object cons {
    val tableNames = arrayOf(
            /*0*/ "shoes",
            /*1*/ "hats",
            /*2*/ "shirt",
            /*3*/ "car"
         )
 }
AllanRibas
sumber