Zeile in SQLite in Android löschen

101

Dies mag eine dumme Frage sein, aber ich bin neu in SQLite und kann das anscheinend nicht herausfinden. Ich habe 1 Tabelle, hat Spalten KEY_ROWID, KEY_NAME, KAY_LATITUDE, undKEY_LONGITUDE . Ich möchte, dass der Benutzer einen auswählen und löschen kann. Kann mir jemand eine Richtung geben, in der ich anfangen soll? Meine Frage ist in der tatsächlichen Löschung der Zeile nur ihren Namen gegeben.

Relevanter Code:

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
quelle
geh mit @iDroid Antwort ... wie es für mich funktionieren wird. Danke iDroid.

Antworten:

182

Sie können Folgendes versuchen:

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

oder

public boolean deleteTitle(String name) 
{
    return db.delete(DATABASE_TABLE, KEY_NAME + "=?", new String[]{name}) > 0;
}
Shreyash Mahajan
quelle
61
Die Antwort von Vijay ist die richtige, da diese Lösung eine SQL-Injektion ermöglicht, die ein Sicherheitsleck darstellt. Beispiel: Verwenden Sie den Wert des Namensarguments: name = "TRUE; <any SQL command>;"=> 'Jeder SQL-Befehl' wird ausgeführt. Natürlich ist es kein Problem, wenn es für diese Funktion keine grafische Benutzeroberfläche gibt.
Bdevay
@bdevay Meine Antwort bezieht sich auf die Hintergrundaufgabe, die wir mit der Abfrage erledigt haben. Es hängt also nicht mit der Benutzeroberfläche zusammen. Sie müssen Informationen nur so dynamisch angeben, dass keine Sicherheit erforderlich ist. Wenn Sie der Antwort des Vijay folgen und jemand Reverse Engineering durchführt, erhalten Sie möglicherweise Informationen zu Tabellen mit in der Datenbank und im Feld, mit denen Sie arbeiten. was ich direkt in der Abfrage mache, so gibt es keine Chance, es Lauch zu haben.
Shreyash Mahajan
@iDroid Explorer: Wenn es keine Benutzereingaben oder andere Möglichkeiten zur Manipulation externer Abfragen gibt, ist das Sicherheitsrisiko natürlich nicht höher als bei der anderen Lösung. Weiter im nächsten Kommentar ...
bdevay
1
... Aber ich stimme dem Reverse Engineering-Teil Ihres Kommentars nicht zu. Sie müssen irgendwo und irgendwie Ihre Abfrage definieren, was bedeutet, dass Reverse Engineering immer ein mögliches Sicherheitsleck ist (auch im Fall Ihrer Lösung), insbesondere in Java, selbst wenn die Quelle verschleiert ist. Es kann nur die Hacking-Zeit mehr erhöhen. Auf der anderen Seite verwendet Googles Empfehlung Auswahlargumente. Bitte überprüfen Sie diesen Artikel: link
bdevay
Ich meine mit dem Konzept, keiner Methode oder Variablen einen statischen Wert zu geben. Das sollte maximal dynamisch sein. Damit es sicherer ist als statischer Wert. Wie auch immer, es liegt beim Benutzer, wie viel Sicherheit er / sie für seine App erstellen möchte.
Shreyash Mahajan
157

Versuchen Sie es so, vielleicht bekommen Sie Ihre Lösung

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

es ist besser, auch whereeargs zu verwenden;

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

Dies ist wie mit diesem Befehl:

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

Die Verwendung der Löschfunktion auf diese Weise ist gut, da dadurch SQL-Injektionen entfernt werden.

Enakhi
quelle
2
Könnten Sie bitte Ihre Antwort näher erläutern und etwas mehr Beschreibung der von Ihnen bereitgestellten Lösung hinzufügen?
Abarisone
1
Ich denke, es lohnt sich, die zu verwenden whereargs.
Msysmilu
@Enkahi Ist das wie vorbereitete Anweisungen in SQLite? Ich habe diese Art von id=?Syntax schon einmal mit PHP verwendet und sie scheint dem sehr ähnlich zu sein.
GeekWithGlasses
17

Bis ich Ihre Frage verstanden habe, möchten Sie zwei Bedingungen festlegen, um eine zu löschende Zeile auszuwählen. Dazu müssen Sie Folgendes tun:

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

Versuchen Sie diesen Code

public void deleteRow(String value)
{
SQLiteDatabase db = this.getWritableDatabase();       
db.execSQL("DELETE FROM " + TABLE_NAME+ " WHERE "+COlUMN_NAME+"='"+value+"'");
db.close();
}
Harman Khera
quelle
Wie nenne ich das, wenn ich löschen möchte? db.deleteRow ();
Phares
Wir können es aufrufen, indem wir den Wert als Parameter übergeben, den Sie löschen möchten. Aufruf als db.deleteRow ("name");
Harman Khera
8

Versuchen Sie diesen Code ...

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

Wenn Sie SQLiteDatabase verwenden gibt es eine

Definition von Löschen

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

Beispielimplementierung

Jetzt können wir eine Methode namens delete mit einem Argument als Namen schreiben

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

Wenn Sie alle Datensätze löschen möchten, übergeben Sie einfach null an die oben beschriebene Methode.

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

Informationsquelle

Jayakrishnan
quelle
Wenn der String-Wert mit dem Fremdschlüssel verbunden ist, dann ??
Harsh Bhavsar
2

Leute, dies ist eine generische Methode, die Sie für alle Ihre Tabellen verwenden können. Hat in meinem Fall perfekt funktioniert.

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
quelle
String.ValueOf (keyValue) => können Sie diese Zeile bitte erklären?
Anis
1
String.ValueOf (keyValue) wird nicht benötigt, da keyValue bereits string ist. In anderen Fällen verwenden wir dieses whereArgs-Array, um den Spaltennamenwert zu identifizieren.
Naveed Ahmad
2

Um Zeilen aus einer Tabelle zu löschen, müssen Sie Auswahlkriterien angeben, die die Zeilen für die delete()Methode identifizieren . Der Mechanismus funktioniert genauso wie die Auswahlargumente für die query()Methode. Es unterteilt die Auswahlspezifikation in eine Auswahlklausel (where-Klausel) und Auswahlargumente.

    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.

Der Rückgabewert für die delete()Methode gibt die Anzahl der Zeilen an, die aus der Datenbank gelöscht wurden.

RAM
quelle
Während dieser Code die Frage möglicherweise beantwortet, verbessert die Bereitstellung eines zusätzlichen Kontexts darüber, warum und / oder wie dieser Code die Frage beantwortet, ihren langfristigen Wert.
Thomas Flinkow
1

Leute, wenn die oben genannten Lösungen für Sie nicht funktionieren, probieren Sie diese auch aus, weil sie für mich funktioniert hat.

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

Funktioniert super!

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

Probier diese:

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

Sie können so etwas tun, indem Sie mein Arbeitscode-Snippet freigeben

Stellen Sie sicher, dass die Abfrage so ist

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();
        }
Hitesh Sahu
quelle
0

Versuchen Sie den folgenden Code-

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

Der einzige Weg, der für mich funktionierte, war dieser

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
quelle