Suppression d'une ligne dans SQLite sous Android


102

C'est peut-être une question stupide, mais je suis nouveau sur SQLite et je n'arrive pas à comprendre cela. J'ai 1 table qui a des colonnes KEY_ROWID, KEY_NAME, KAY_LATITUDE, et KEY_LONGITUDE. Je veux que l'utilisateur puisse en sélectionner un et le supprimer; Quelqu'un peut-il me donner une direction pour commencer? Ma question porte sur la suppression effective de la ligne qui ne porte que sur son nom.

Code pertinent:

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

allez avec @iDroid answer ... car cela fonctionnera pour moi. Merci iDroid.

Réponses:


183

Vous pouvez essayer comme ceci:

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

ou

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

61
La réponse de Vijay est la bonne car cette solution permet de faire une injection SQL qui est une fuite de sécurité. Par exemple: utilisez la valeur de l'argument nom: name = "TRUE; <any SQL command>;"=> 'toute commande SQL' sera exécutée. Bien sûr, ce n'est pas un problème s'il n'y a pas d'interface graphique pour cette fonctionnalité.
bdevay

@bdevay Ma réponse concerne la tâche d'arrière-plan que nous avons effectuée avec la requête. Ce n'est donc pas lié à l'interface utilisateur. Il vous suffit de donner des informations de manière aussi dynamique afin qu'il n'y ait pas besoin de sécurité. Si vous suivez la réponse de vijay et que quelqu'un fait de l'ingénierie inverse, vous pourriez avoir des informations sur la table avec dans la base de données et le champ que vous comparez. ce que je fais directement dans la requête, donc il n'y a aucune chance de l'avoir poireau.
Shreyash Mahajan

@iDroid Explorer: bien sûr, s'il n'y a pas d'entrée utilisateur ou autre type de possibilité de manipulation de requête externe, le risque de sécurité n'est pas plus élevé qu'avec l'autre solution. Continuer dans le prochain commentaire ...
bdevay

1
... Mais je ne suis pas d'accord avec la partie rétro-ingénierie de votre commentaire. Vous devez définir quelque part et d'une manière ou d'une autre votre requête, ce qui signifie que l'ingénierie inverse est toujours une fuite de sécurité possible (même dans le cas de votre solution), en particulier en Java même si la source est obscurcie. Cela ne peut que prolonger davantage le temps de piratage. D'autre part, la recommandation de Google utilise des arguments de sélection, veuillez consulter cet article: lien
bdevay

Je veux dire avec le concept de ne pas donner de valeur statique à n'importe quelle méthode ou n'importe quelle variable. Cela devrait être le maximum de dynamique. Pour qu'il soit plus sûr que de donner une valeur statique. Quoi qu'il en soit, c'est à l'utilisateur de déterminer à quel point il souhaite sécuriser son application.
Shreyash Mahajan

157

Essayez comme ça pour avoir votre solution

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

58

il vaut mieux aussi utiliser des objets;

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

c'est comme utiliser cette commande:

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

et l'utilisation de la fonction de suppression de cette manière est bonne car elle supprime les injections SQL.


2
Pourriez-vous s'il vous plaît préciser votre réponse en ajoutant un peu plus de description de la solution que vous fournissez?
abarisone

1
Je pense que cela vaut la peine d'utiliser le whereargs.
msysmilu

@Enkahi Est-ce que c'est comme des instructions préparées dans SQLite? J'ai déjà utilisé ce id=?genre de syntaxe avec PHP et cela semble très similaire à cela.
GeekWithGlasses

17

Jusqu'à ce que je comprenne votre question, vous souhaitez mettre deux conditions pour sélectionner une ligne à supprimer.Pour cela, vous devez faire:

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

Essayez ce code

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

Comment appeler cela lorsque je souhaite supprimer? db.deleteRow ();
Phares

nous pouvons l'appeler en passant la valeur comme paramètre que vous souhaitez supprimer. Appelez en tant que db.deleteRow ("nom");
Harman Khera

8

Essayez ce code ...

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


3

si vous utilisez SQLiteDatabase, il existe une méthode de suppression

Définition de la suppression

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

Exemple d'implémentation

Maintenant, nous pouvons écrire une méthode appelée delete avec l'argument comme nom

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

si vous souhaitez supprimer tous les enregistrements, passez simplement null à la méthode ci-dessus,

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

Source d'information


Si la valeur de chaîne est attachée avec une clé étrangère, alors ??
Harsh Bhavsar

2

Les gars, c'est une méthode générique que vous pouvez utiliser pour toutes vos tables, a parfaitement fonctionné dans mon cas.

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) => pouvez-vous expliquer cette ligne?
Anis

1
Pas besoin de String.ValueOf (keyValue), car la keyValue est déjà string. dans d'autres cas, nous utilisons ce whereArgs Array pour identifier la valeur du nom de la colonne.
Naveed Ahmad

2

Pour supprimer des lignes d'une table, vous devez fournir des critères de sélection qui identifient les lignes de la delete()méthode. Le mécanisme fonctionne de la même manière que les arguments de sélection de la query()méthode. Il divise la spécification de sélection en une clause de sélection (clause where) et des arguments de sélection.

    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.

La valeur de retour de la delete()méthode indique le nombre de lignes qui ont été supprimées de la base de données.


Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire concernant la raison et / ou la manière dont ce code répond à la question améliore sa valeur à long terme.
Thomas Flinkow

1

Les gars si les solutions ci-dessus ne fonctionnent pas pour vous, essayez celle-ci aussi parce que cela a fonctionné pour moi.

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

1

Fonctionne très bien!

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

0

Essaye celui-là:

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

Vous pouvez faire quelque chose comme ça, partager mon extrait de code de travail

Assurez-vous que la requête est comme ça

DELETE FROM tableName WHERE KEY__NAME = 'paramètreToMatch'

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

Essayez le code ci-dessous-

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

La seule façon qui a fonctionné pour moi était ceci

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"
         )
 }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.