在Android中删除SQLite中的行


102

这可能是一个愚蠢的问题,但是我是SQLite的新手,我似乎无法弄清楚。我有了列1台KEY_ROWIDKEY_NAMEKAY_LATITUDE,和KEY_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。

Answers:


183

您可以这样尝试:

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

61
Vijay的答案是正确的,因为此解决方案允许进行SQL注入,这是安全漏洞。例如:使用名称参数的值:name = "TRUE; <any SQL command>;"=>将执行“任何SQL命令”。当然,如果没有针对该功能的GUI,这也不是问题。
bdevay 2014年

@bdevay我的答案是关于我们通过查询完成的后台任务。因此它与UI无关。您只需要动态地提供信息即可,因此无需安全性。如果您遵循vijay的回答,并且有人进行了反向工程,那么您可能会在数据库和要编辑的字段中获得有关table的信息。我直接在查询中这样做,所以没有机会韭菜。
Shreyash Mahajan 2014年

@iDroid Explorer:当然,如果没有用户输入或其他类型的外部查询操作可能性,则安全风险不会比其他解决方案高。继续在下
一条

1
...但是我不同意您评论中的逆向工程部分。您必须以某种方式定义查询,这意味着逆向工程始终是可能的安全漏洞(即使在您的解决方案中也是如此),尤其是在Java中,即使混淆了源代码也是如此。它只会增加更多的黑客时间。另一方面,Google的建议是使用选择参数,请查看本文:链接
bdevay 2014年

我的意思是不给任何方法或变量提供静态值的概念。那应该是最大的动力。这样一来,与提供静态值相比,它更加安全。无论如何,要由用户决定他/她想要制作他们的应用程序的安全性。
Shreyash Mahajan 2014年

157

这样尝试,可能会找到解决方案

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

58

最好也使用whereargs;

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

这就像使用以下命令:

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

并且以这种方式使用delete函数是很好的,因为它可以删除sql注入。


2
您能否详细说明您的答案,并提供有关您提供的解决方案的更多说明?
abarisone 2015年

1
我认为值得使用whereargs
msysmilu 2015年

@Enkahi这就像SQLite中的准备好的语句吗?我以前id=?在PHP上使用过这种语法,似乎与此非常相似。
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);
      */  

}

13

试试这个代码

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

我要删除该怎么称呼?db.deleteRow();
法尔兹

我们可以通过传递值作为要删除的参数来调用它。调用为db.deleteRow(“ name”);
哈曼·凯拉

8

试试这个代码...

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


3

如果您使用的是SQLiteDatabase, 则有一个delete方法

删除的定义

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

示例实施

现在我们可以编写一个名为delete的方法,其参数为name

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

信息来源


如果String值附加有外键,则??
哈什·巴甫萨尔

2

伙计们,这是可用于所有表格的通用方法,在我的情况下效果很好。

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)=>您能解释一下这一行吗?
阿尼斯(Anis)2015年

1
不需要String.ValueOf(keyValue),因为keyValue已经是字符串。在其他情况下,我们使用whereArgs Array标识列名值。
Naveed Ahmad 2015年

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.

delete()方法的返回值指示从数据库中删除的行数。


尽管此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以改善其长期价值。
Thomas Flinkow

1

如果上述解决方案对您不起作用,请尝试使用此解决方案,因为它对我有用。

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

1

很棒!

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


0
public boolean deleteRow(long l) {
    String where = "ID" + "=" + l;
    return db.delete(TABLE_COUNTRY, where, null) != 0;
}

0

您可以执行以下操作,共享我的工作代码段

确保查询是这样的

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

0

尝试以下代码-

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

对我有用的唯一方法是

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"
         )
 }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.