在Android中删除SQLite中的行

111
这可能是一个愚蠢的问题,但我是SQLite的新手,似乎无法解决这个问题。我有一个表,其中包含列KEY_ROWIDKEY_NAMEKAY_LATITUDEKEY_LONGITUDE。我希望用户能够选择其中一个并将其删除;有没有人能给我一个起点方向?我的问题在于仅凭其名称删除行的实际删除。
相关代码:
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);
        }
    }
}

跟随 @iDroid 的答案...因为它对我有效。感谢 iDroid。 - user644458
18个回答

195

您可以尝试像这样:

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

或者

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

70
Vijay的答案是正确的,因为这种解决方案可以进行SQL注入,这会造成安全漏洞。例如:使用名称参数的值:name = "TRUE; <any SQL command>;" => '任何SQL命令'将被执行。当然,如果该功能没有图形用户界面,则不是问题。 - bdevay
2
... 但是我不同意你评论中的逆向工程部分。你必须在某个地方和某种方式定义你的查询,这意味着逆向工程始终可能存在安全漏洞(即使在你的解决方案中),尤其是在Java中,即使源代码被混淆。它只会增加黑客攻击的时间。另一方面,谷歌的建议是使用选择参数,请查看这篇文章:链接 - bdevay
@iDroidExplorer,我看到了这个答案,很喜欢,但我想问一下你是如何处理来自Activity的querty的。我已经卡在这里很长时间了,请帮帮我。 - Steve Kamau
@SteveKamau,希望你已经创建了DatabaseHelper类,在其中执行所有与数据库相关的操作。在这里,您可以放置此方法,并通过创建此DatabaseHelper类的对象从任何活动中使用它。 - Shreyash Mahajan
@iDroidExplorer请在这里查看我的问题-->https://dev59.com/D4zda4cB1Zd3GeqPn46a?noredirect=1#comment50334196_31161944 - Steve Kamau
显示剩余5条评论

164

尝试像这样,也许你会得到解决方案

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

64

最好也使用 whereargs;

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

这就像使用这个命令:

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

使用delete函数的方式是不错的,因为它可以防止SQL注入攻击。


2
您能否详细阐述一下您的答案,并对您提供的解决方案进行更多描述? - abarisone
1
我认为使用 whereargs 是值得的。 - msysmilu
@Enkahi 这是否类似于 SQLite 中的预处理语句?我之前在 PHP 中使用过 id=? 这样的语法,它看起来非常相似。 - GeekWithGlasses

17

在我理解你的问题之前,你想要添加两个条件来选择要删除的行。为此,你需要执行以下操作:

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

}

15

尝试这段代码

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

当我想要删除时,我该如何调用它?db.deleteRow(); - Phares
我们可以通过将想要删除的值作为参数传递来调用它。调用方式为 db.deleteRow("name"); - Harman Khera

8

试试这段代码...

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

6

这个完美地工作了:

public boolean deleteSingleRow(String rowId) 
{
    return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}

您还可以参考这个例子

相关链接已失效,正确的链接是http://web.archive.org/web/20110309080938/http://blog.sptechnolab.com/2011/03/02/mysql/android-sqlite-insert-update-delete-and-display-data/。 - Navoneel Talukdar

3

如果您正在使用 SQLiteDatabase,那么有一个删除方法。

删除的定义:

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

示例实现

现在我们可以编写一个名为带参数删除的方法

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

如果你想要删除所有记录,只需要将null传递给上述方法即可。

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

Source Of Information


如果字符串值附加了外键,那么?? - Harsh Bhavsar

2
尝试下面的代码 -
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.
}

2
要从表中删除行,您需要提供选择条件来标识要在delete()方法中删除的行。该机制与query()方法的选择参数相同。它将选择规范分成选择子句(where子句)和选择参数。
    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.
< p > delete() 方法的返回值表示从数据库中删除的行数。


尽管这段代码可能回答了问题,但提供有关为什么和/或如何回答问题的附加上下文可以提高其长期价值。 - Thomas Flinkow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接