Eliminazione di una riga in SQLite in Android


102

Questa potrebbe essere una domanda stupida, ma sono nuovo di SQLite e non riesco a capirlo. Ho 1 tabella che ha le colonne KEY_ROWID, KEY_NAME, KAY_LATITUDE, e KEY_LONGITUDE. Voglio che l'utente possa selezionarne uno ed eliminarlo; Qualcuno può darmi una direzione per iniziare? La mia domanda è nell'effettiva cancellazione della riga data solo il suo nome.

Codice rilevante:

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

vai con la risposta di @iDroid ... poiché funzionerà per me. Grazie iDroid.

Risposte:


183

Puoi provare in questo modo:

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

o

public boolean deleteTitle(String name) 
{
    return db.delete(DATABASE_TABLE, KEY_NAME + "=?", new String[]{name}) > 0;
}

61
La risposta di Vijay è corretta perché questa soluzione permette di fare un'iniezione SQL che è una falla di sicurezza. Ad esempio: usa il valore dell'argomento nome: name = "TRUE; <any SQL command>;"=> 'qualsiasi comando SQL' verrà eseguito. Ovviamente non è un problema se non c'è una GUI per quella funzione.
bdevay

@bdevay La mia risposta riguarda l'attività in background che abbiamo eseguito con la query. Quindi non è correlato all'interfaccia utente. Devi solo fornire le informazioni in modo dinamico, quindi non c'è bisogno di sicurezza. Se segui la risposta di vijay e qualcuno esegue il reverse engineering, potresti ottenere informazioni sulla tabella nel database e nel campo che stai cercando. cosa che sto facendo direttamente nella query quindi non c'è possibilità di averlo porro.
Shreyash Mahajan

@iDroid Explorer: ovviamente se non ci sono input dell'utente o altri tipi di possibilità di manipolazione delle query esterne, il rischio per la sicurezza non è maggiore rispetto all'altra soluzione. Continua nel prossimo commento ...
bdevay

1
... Ma non sono d'accordo con la parte di reverse engineering del tuo commento. Devi definire da qualche parte e in qualche modo la tua query, il che significa che il reverse engineering è sempre una possibile falla di sicurezza (anche nel caso della tua soluzione), specialmente in Java anche se la fonte è offuscata. Può solo aumentare ulteriormente il tempo di hacking. D'altra parte, la raccomandazione di Google utilizza argomenti di selezione, controlla questo articolo: link
bdevay

Intendo con il concetto di non dare valore statico a qualsiasi metodo o variabile. Dovrebbe essere il massimo della dinamica. In modo che sia più sicuro quindi dare valore statico. Ad ogni modo spetta all'utente decidere quanto sicuro vuole rendere la propria app.
Shreyash Mahajan

157

Prova così potresti ottenere la tua soluzione

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

58

è meglio usare anche i WHOARGS;

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

è come usare questo comando:

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

e l'utilizzo della funzione di cancellazione in questo modo è utile perché rimuove le iniezioni sql.


2
Potresti elaborare maggiormente la tua risposta aggiungendo un po 'più di descrizione sulla soluzione che fornisci?
abarisone

1
Penso che valga la pena usare il whereargs.
msysmilu

@ Enkahi È come le istruzioni preparate in SQLite? Ho già usato questo tipo di id=?sintassi con PHP e mi sembra molto simile.
GeekWithGlasses

17

Finché non capisco la tua domanda, vuoi mettere due condizioni per selezionare una riga da eliminare. Per questo, devi fare:

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);
      */  

}

13

Prova questo codice

public void deleteRow(String value)
{
SQLiteDatabase db = this.getWritableDatabase();       
db.execSQL("DELETE FROM " + TABLE_NAME+ " WHERE "+COlUMN_NAME+"='"+value+"'");
db.close();
}

Come lo chiamo quando voglio eliminare? db.deleteRow ();
Phares

possiamo chiamarlo passando valore come parametro che vuoi eliminare. Chiama come db.deleteRow ("name");
Harman Khera

8

Prova questo codice ...

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


3

se stai usando SQLiteDatabase, esiste un metodo di eliminazione

Definizione di Delete

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

Esempio di implementazione

Ora possiamo scrivere un metodo chiamato delete con argomento come nome

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

se vuoi eliminare tutti i record, passa semplicemente null al metodo sopra,

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

Fonte d'informazione


Se il valore String è collegato con una chiave esterna, allora ??
Harsh Bhavsar

2

Ragazzi questo è un metodo generico che puoi usare per tutte le tue tabelle, ha funzionato perfettamente nel mio caso.

public void deleteRowFromTable(String tableName, String columnName, String keyValue) {
    String whereClause = columnName + "=?";
    String[] whereArgs = new String[]{String.valueOf(keyValue)};
    yourDatabase.delete(tableName, whereClause, whereArgs);
}

String.ValueOf (keyValue) => puoi spiegare questa riga?
Anis

1
Non c'è bisogno di String.ValueOf (keyValue), perché keyValue è già stringa. in altri casi stiamo usando questo whereArgs Array per identificare il valore del nome della colonna.
Naveed Ahmad

2

Per eliminare righe da una tabella, è necessario fornire criteri di selezione che identificano le righe nel delete()metodo. Il meccanismo funziona allo stesso modo degli argomenti di selezione del query()metodo. Divide la specifica di selezione in una clausola di selezione (clausola where) e argomenti di selezione.

    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.

Il valore restituito per il delete()metodo indica il numero di righe eliminate dal database.


Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo sul perché e / o come questo codice risponde alla domanda ne migliora il valore a lungo termine.
Thomas Flinkow

1

Ragazzi, se le soluzioni di cui sopra non funzionano per te, prova questa anche perché ha funzionato per me.

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

1

Funziona alla grande!

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

0

Prova questo:

public void deleteEntry(long rowId) {
    database.delete(DATABASE_TABLE , KEY_ROWID 
        + " = " + rowId, null);}

0
public boolean deleteRow(long l) {
    String where = "ID" + "=" + l;
    return db.delete(TABLE_COUNTRY, where, null) != 0;
}

0

Puoi fare qualcosa del genere, condividendo il mio snippet di codice funzionante

Assicurati che la query sia così

DELETE FROM 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();
        }

0

Prova il codice seguente-

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

0

L'unico modo che ha funzionato per me era questo

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"
         )
 }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.