Eliminando Row en SQLite en Android

102

Esta puede ser una pregunta tonta, pero soy nuevo en SQLite y parece que no puedo resolver esto. Tengo 1 tabla que tiene columnas KEY_ROWID, KEY_NAME, KAY_LATITUDE, y KEY_LONGITUDE. Quiero que el usuario pueda seleccionar uno y eliminarlo; ¿Alguien puede darme una dirección para empezar? Mi pregunta está en la eliminación real de la fila dada solo su nombre.

Código relevante:

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
fuente
vaya con la respuesta @iDroid ... ya que va a funcionar para mí. Gracias iDroid.

Respuestas:

183

Puedes probar así:

 //---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;
}
Shreyash Mahajan
fuente
61
La respuesta de Vijay es la correcta porque esta solución permite hacer una inyección SQL que es una fuga de seguridad. Por ejemplo: use el valor del argumento de nombre: name = "TRUE; <any SQL command>;"=> se ejecutará 'cualquier comando SQL'. Por supuesto, no es un problema si no hay una GUI para esa función.
bdevay
@bdevay Mi respuesta es sobre la tarea en segundo plano que hicimos con query. Por tanto, no está relacionado con la interfaz de usuario. Solo tiene que proporcionar información de forma dinámica para que no haya necesidad de seguridad. Si sigue la respuesta de vijay y alguien hace ingeniería inversa, es posible que obtenga información sobre la tabla en la base de datos y el campo que está comprando. que estoy haciendo directamente en la consulta, por lo que no hay posibilidad de que tenga puerro.
Shreyash Mahajan
@iDroid Explorer: por supuesto, si no hay una entrada del usuario u otro tipo de posibilidad de manipulación de consultas externas, el riesgo de seguridad no es mayor que con la otra solución. Continuar en el siguiente comentario ...
bdevay
1
... Pero no estoy de acuerdo con la parte de ingeniería inversa de su comentario. Debe definir en algún lugar y de alguna manera su consulta, lo que significa que la ingeniería inversa siempre es una posible fuga de seguridad (incluso en el caso de su solución), especialmente en Java, incluso si la fuente está ofuscada. Solo puede aumentar más el tiempo de pirateo. Por otro lado, la recomendación de Google es utilizar argumentos de selección, consulte este artículo: enlace
bdevay
Me refiero al concepto de no dar valor estático a ningún método o variable. Eso debería ser el máximo de dinámico. Para que sea más seguro que dar valor estático. De todos modos, depende del usuario qué tan segura quiere hacer su aplicación.
Shreyash Mahajan
157

Intenta así, puede que obtengas tu solución

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

es mejor usar whereargs también;

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

esto es como usar este comando:

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

y usar la función de eliminación de esa manera es bueno porque elimina las inyecciones de SQL.

Enakhi
fuente
2
¿Podría elaborar más su respuesta agregando un poco más de descripción sobre la solución que proporciona?
abarisone
1
Creo que vale la pena usar el whereargs.
msysmilu
@Enkahi ¿Es esto como declaraciones preparadas en SQLite? He usado este id=?tipo de sintaxis con PHP antes y parece muy similar a eso.
GeekWithGlasses
17

Hasta que entienda su pregunta, desea poner dos condiciones para seleccionar una fila que se eliminará. Para eso, debe hacer:

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
fuente
13

Prueba este código

public void deleteRow(String value)
{
SQLiteDatabase db = this.getWritableDatabase();       
db.execSQL("DELETE FROM " + TABLE_NAME+ " WHERE "+COlUMN_NAME+"='"+value+"'");
db.close();
}
Harman Khera
fuente
¿Cómo llamo a esto cuando quiero eliminar? db.deleteRow ();
Phares
podemos llamarlo pasando el valor como parámetro que desea eliminar. Llamar como db.deleteRow ("nombre");
Harman Khera
8

Prueba este código ...

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

si está utilizando SQLiteDatabase, entonces hay un método de eliminación

Definición de eliminar

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

Implementación de ejemplo

Ahora podemos escribir un método llamado eliminar con un argumento como nombre

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

si desea eliminar todos los registros , simplemente pase nulo al método anterior,

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

Fuente de información

Jayakrishnan
fuente
Si el valor de cadena se adjunta con una clave externa, entonces ??
Harsh Bhavsar
2

Chicos, este es un método genérico que pueden usar para todas sus tablas, funcionó perfectamente en mi 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);
}
Naveed Ahmad
fuente
String.ValueOf (keyValue) => ¿puede explicar esta línea?
Anis
1
No es necesario String.ValueOf (keyValue), porque el keyValue ya es una cadena. en otros casos, estamos usando esta matriz whereArgs para identificar el valor del nombre de la columna.
Naveed Ahmad
2

Para eliminar filas de una tabla, debe proporcionar criterios de selección que identifiquen las filas del delete()método. El mecanismo funciona igual que los argumentos de selección del query()método. Divide la especificación de selección en una cláusula de selección (cláusula where) y argumentos de selección.

    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.

El valor de retorno del delete()método indica el número de filas que se eliminaron de la base de datos.

RAM
fuente
Si bien este código puede responder a la pregunta, proporcionar un contexto adicional sobre por qué y / o cómo este código responde a la pregunta mejora su valor a largo plazo.
Thomas Flinkow
1

Chicos, si las soluciones anteriores no funcionan para ustedes, intenten esta también porque funcionó para mí.

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

¡Funciona genial!

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

Prueba este:

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

Puedes hacer algo como esto, compartiendo mi fragmento de código de trabajo

Asegúrate de que la consulta sea así

ELIMINAR DE tableName DONDE 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
fuente
0

Pruebe el siguiente código

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
fuente
0

La única forma que funcionó para mí fue esta

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
fuente