การลบแถวใน SQLite ใน Android


102

นี่อาจเป็นคำถามที่โง่ แต่ฉันยังใหม่กับ SQLite และดูเหมือนจะคิดไม่ออก ฉันมี 1 ตารางที่มีคอลัมน์KEY_ROWID, KEY_NAME, KAY_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

คำตอบ:


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

@bdevay คำตอบของฉันเกี่ยวกับงานเบื้องหลังที่เราทำด้วยแบบสอบถาม ดังนั้นจึงไม่เกี่ยวข้องกับ UI คุณต้องให้ข้อมูลแบบไดนามิกจึงไม่จำเป็นต้องมีความปลอดภัย หากคุณทำตามคำตอบของวีเจย์และบางคนทำวิศวกรรมย้อนกลับคุณอาจได้รับข้อมูลเกี่ยวกับตารางในฐานข้อมูลและฟิลด์ที่คุณกำลังคำนวณ ซึ่งฉันทำโดยตรงในแบบสอบถามดังนั้นจึงไม่มีโอกาสที่จะได้กระเทียม
Shreyash Mahajan

@iDroid Explorer: แน่นอนว่าหากไม่มีการป้อนข้อมูลของผู้ใช้หรือความเป็นไปได้ในการจัดการแบบสอบถามภายนอกประเภทอื่นความเสี่ยงด้านความปลอดภัยจะไม่สูงไปกว่าโซลูชันอื่น ๆ ต่อในความคิดเห็นถัดไป ...
bdevay

1
... แต่ฉันไม่เห็นด้วยกับส่วนวิศวกรรมย้อนกลับในความคิดเห็นของคุณ คุณต้องกำหนดที่ใดที่หนึ่งและคำค้นหาของคุณซึ่งหมายความว่าการทำวิศวกรรมย้อนกลับมักจะมีการรั่วไหลของความปลอดภัยที่เป็นไปได้ (แม้ในกรณีของโซลูชันของคุณ) โดยเฉพาะใน Java แม้ว่าแหล่งที่มาจะสับสน สามารถเพิ่มเวลาในการแฮ็กได้มากขึ้นเท่านั้น ในทางกลับกันคำแนะนำของ Google ใช้อาร์กิวเมนต์การเลือกโปรดตรวจสอบบทความนี้: link
bdevay

ฉันหมายถึงแนวคิดที่จะไม่ให้ค่าคงที่กับวิธีการใด ๆ หรือตัวแปรใด ๆ ซึ่งควรเป็นค่าสูงสุดแบบไดนามิก เพื่อให้มีความปลอดภัยมากขึ้นจากนั้นจึงให้ค่าคงที่ ทั้งนี้ขึ้นอยู่กับผู้ใช้ว่าต้องการให้แอปมีความปลอดภัยมากน้อยเพียงใด
Shreyash Mahajan

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'

และการใช้ฟังก์ชั่นลบด้วยวิธีนี้เป็นสิ่งที่ดีเพราะมันลบการฉีด sql


2
โปรดอธิบายเพิ่มเติมเกี่ยวกับคำตอบของคุณโดยเพิ่มคำอธิบายเพิ่มเติมเล็กน้อยเกี่ยวกับโซลูชันที่คุณให้มาได้ไหม
หอยเป๋าฮื้อ

1
ฉันคิดว่ามันคุ้มค่าที่จะใช้ไฟล์whereargs.
msysmilu

@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 ();
Phares

เราสามารถเรียกมันได้โดยส่งค่าเป็นพารามิเตอร์ที่คุณต้องการลบ เรียกเป็น db.deleteRow ("name");
Harman Khera

8

ลองใช้รหัสนี้ ...

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

5

สิ่งนี้ทำงานได้อย่างสมบูรณ์:

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

คุณยังสามารถอ้างถึงตัวอย่างนี้


ลิงค์ที่เกี่ยวข้องตายไปแล้วตอนนี้ที่ถูกต้องคือweb.archive.org/web/20110309080938/http://blog.sptechnolab.com/…
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);
}

แหล่งข้อมูล


ถ้าค่า String ถูกแนบด้วย Foreign Key แล้ว ??
Harsh Bhavsar

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

1
ไม่จำเป็นต้องใช้ String.ValueOf (keyValue) เนื่องจาก keyValue เป็นสตริงอยู่แล้ว ในกรณีอื่น ๆ เรากำลังใช้สิ่งนี้โดยที่ Args Array เพื่อระบุค่าชื่อคอลัมน์
Naveed Ahmad

2

ในการลบแถวออกจากตารางคุณต้องระบุเกณฑ์การเลือกที่ระบุแถวในdelete()วิธีการ กลไกทำงานเหมือนกับอาร์กิวเมนต์การเลือกของquery()วิธีการ แบ่งข้อกำหนดการเลือกออกเป็นประโยคการเลือก (โดยที่ข้อ) และอาร์กิวเมนต์การเลือก

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




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"
         )
 }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.