111 votes

Suppression d'un rang dans SQLite sous Android

C'est peut-être une question stupide, mais je suis nouveau dans le monde de SQLite et je n'arrive pas à comprendre ce qui se passe. J'ai une 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 à suivre ? Ma question porte sur la suppression effective de la ligne, compte tenu uniquement de 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);
        }
    }
}

0 votes

Allez avec la réponse de @iDroid... car elle va fonctionner pour moi. Merci iDroid.

195voto

iDroid Explorer Points 7726

Vous pouvez essayer comme ça :

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

70 votes

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 : utiliser 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é.

0 votes

@bdevay Ma réponse concerne la tâche de fond que nous effectuons avec la requête. Elle n'est donc pas liée à l'interface utilisateur. Il suffit de donner des informations de manière dynamique pour qu'il n'y ait pas besoin de sécurité. Si vous suivez la réponse de Vijay et que quelqu'un fait de la rétro-ingénierie, vous pourriez obtenir des informations sur la table dans la base de données et sur le champ que vous comparez, ce que je fais directement dans la requête, donc il n'y a aucune chance que ce soit du vent.

0 votes

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

164voto

Vijay Points 385

Essayez comme ça, vous obtiendrez peut-être votre solution

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

64voto

Enakhi Points 762

Il est préférable d'utiliser aussi les whereargs ;

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 delete de cette manière est bonne car elle élimine les injections sql.

2 votes

Pourriez-vous élaborer davantage votre réponse en décrivant un peu plus la solution que vous proposez ?

1 votes

Je pense qu'il vaut la peine d'utiliser le whereargs .

0 votes

@Enkahi Est-ce que c'est comme les instructions préparées dans SQLite ? J'ai utilisé ceci id=? une sorte de syntaxe avec PHP auparavant et cela semble très similaire à cela.

17voto

Hiral Points 7845

Jusqu'à ce que je comprenne votre question, vous voulez 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);
      */  

}

15voto

Harman Khera Points 218

Essayez ce code

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

0 votes

Comment puis-je l'appeler lorsque je veux supprimer ? db.deleteRow() ;

0 votes

Nous pouvons l'appeler en passant comme paramètre la valeur que vous voulez supprimer. Appeler comme db.deleteRow("nom") ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X