我正在使用sqlite,并且在从listview中填充的sqlite中删除数据时出现问题。在logcat中没有错误。所选项目的ID是toast.But无法从数据库中删除数据。 如果我逐个删除每一行,那么在那里找不到数据,但是当我添加一些新数据后,删除的数据也在那里。 当我点击名为viewinfo的按钮时,在listview中重复最后一个条目。
这是从sqlite中删除存储在listview
中的数据的代码 public Integer deleteData(String position){
SQLiteDatabase db=getWritableDatabase();
return db.delete(Table_N," ID = ? ",new String[]{position});
}
这是从listview
删除数据的代码public void viewinformation() {
dataKASPER.getWritableDatabase();
Cursor cursor = dataKASPER.getAllData();
if (cursor.getCount() == 0) {
Toast.makeText(this, "data is not there", Toast.LENGTH_SHORT).show();
} else {
while (cursor.moveToNext()) {
Names_araylist.add(cursor.getString(1).toString());
Designation_arraylist.add(cursor.getString(2).toString());
adapter=new lisadapter(Infolist.this,Names_araylist,Designation_arraylist);
mlistview.setAdapter(adapter);
mlistview.setOnItemClickListener(this);
mlistview.setOnItemLongClickListener(this);
}
}
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent=new Intent(Infolist.this,Viewallinfo.class);
startActivity(intent);
}
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
final String id= String.valueOf(l);
final AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("Warning");
builder.setMessage("Want You Delete This Record??");
builder.setPositiveButton("yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dataKASPER.deleteData(id);
adapter.notifyDataSetChanged();
Toast.makeText(Infolist.this,id, Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
builder.setCancelable(true);
}
});
builder.show();
return true;
}
请告诉我如何正确删除数据库中的数据。
答案 0 :(得分:0)
看起来问题是您尝试使用数值删除名称。
传递到l
方法的 onItemLongClick
(长整数)是相应的 _id
列行,用于分配给字符串变量 id
,然后传递给deleteData
方法。
这会尝试删除 Name
作为id的行(即行_id列值)。修复似乎是要改变: -
return db.delete(Table_N," Name = ? ",new String[]{position});
到
<强> return db.delete(Table_N," _id = ? ",new String[]{position});
强>
即。删除行_id列是传递给onItemLongClick
方法的_id的值。
根据评论表明,表格中没有_id : -
好的,然后 l 根据
基本没用来自AdapterView.OnItemLongClickListener的id long:已点击的项目的行ID
。
您需要通过位置确定并提取名称。 l ,因此 id 很可能不会是名称,因此不太可能使用 l 会导致任何行被删除。
如何利用位置取决于输入适配器的数据源,无论是数组还是光标。 位置将是相应的数组索引或光标内的相应位置。或者,您也可以使用getSelectedItem()来检索
与当前所选项目对应的数据,如果是,则为null 没有选择
作为对象。来自AdapterView - getSelectedItem
但是,如果名称不是唯一的,使用return db.delete(Table_N," Name = ? ",new String[]{position});
可能会导致删除多行。
我还没有测试的另一个选项是使用 rowid (除非编写了WITHOUT ROWID,否则每个表都有)(如果 l 获得rowid,则_id不存在,这是我没有经过测试的方面。
ROWID和INTEGER PRIMARY KEY
除WITHOUT ROWID表外,SQLite表中的所有行都有一个 64位有符号整数键,用于唯一标识其中的行 表。这个整数通常称为&#34; rowid&#34;。 rowid值可以 使用一个与特殊情况无关的名称&#34; rowid&#34;进行访问, &#34; oid&#34;,或&#34; rowid &#34;代替列名称。如果一个表包含一个 用户定义的列名为&#34; rowid&#34;,&#34; oid&#34;或&#34; rowid &#34;,然后该名称 始终引用显式声明的列,不能用于 检索整数rowid值。 来自SQL As Understood By SQLite - CREATE TABLE
假设 l 确实返回相应的rowid
,那么编码return db.delete(Table_N," rowid = ? ",new String[]{position});
就可以了。
如果adpapter的数据源是Cursor,那么您可以创建_id作为rowid的别名,因此上面的内容可以正常工作。例如SELECT Name, rowid AS _id FROM yourtable
。
如果适配器的数据源是阵列,那么使用rowid
不是一个选项。
编辑您的问题以包含实例化适配器的代码和创建数据源的代码将使得能够给出更具体的答案。
这里有一些基本的代码可以做你想要的,但使用一个简单的适配器: -
首先是布局( activity_main.xml ,它只有一个ListView,这里没什么特别的): -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="mjt.so44730629.MainActivity">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
DBHelper ,请注意我已经包含了各种方法,例如返回String ArrayLists的方法: -
public class dataKasper extends SQLiteOpenHelper {
public final static String DBDATABASENAME = "kasper";
public final static int DBVERSION = 1;
public final static String DBTABLENAME = "Table_N";
public final static String DBIDCOLNAME = "ID";
public final static String DBNAMECOLNAME = "Name";
public final static String DBCREATESQL = "CREATE TABLE " +
DBTABLENAME + "(" +
DBIDCOLNAME + " INTEGER PRIMARY KEY," +
DBNAMECOLNAME + " TEXT" +
");";
public final static String DBORDERBYID = DBIDCOLNAME;
private int tcount;
public dataKasper(Context context) {
super(context,DBDATABASENAME,null,DBVERSION);
tcount = 0;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DBCREATESQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int newversion, int oldversion) {
}
public void deleteData(int id) {
SQLiteDatabase db = this.getWritableDatabase();
String whereclause = DBIDCOLNAME + "=?";
String[] whereargs = new String[]{Long.toString(id)};
db.delete(DBTABLENAME,whereclause,whereargs);
db.close();
}
public void deleteDataByName(String Name) {
SQLiteDatabase db = getWritableDatabase();
String whereclause = DBNAMECOLNAME + "=?";
String[] whereargs = new String[]{Name};
db.delete(DBTABLENAME,whereclause,whereargs);
db.close();
}
public Cursor getAllData() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor rv = db.query(DBTABLENAME,null,null,null,null,null,DBORDERBYID);
tcount = rv.getCount();
return rv;
}
public int getAllRowCount() {
SQLiteDatabase db = getReadableDatabase();
Cursor allrows = db.query(DBTABLENAME,null,null,null,null,null,null);
int rv = allrows.getCount();
allrows.close();
db.close();
return rv;
}
public void insertRow(String Name) {
SQLiteDatabase db = getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(DBNAMECOLNAME,Name);
db.insert(DBTABLENAME,null,cv);
db.close();
}
public ArrayList<String> getAllNames() {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<String> rv = new ArrayList<>();
Cursor alldata = getAllData();
while (alldata.moveToNext()) {
rv.add(alldata.getString(alldata.getColumnIndex(DBNAMECOLNAME)));
}
alldata.close();
db.close();
return rv;
}
public ArrayList<String> getAllIDS() {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<String> rv = new ArrayList<>();
Cursor alldata = getAllData();
while (alldata.moveToNext()) {
rv.add(alldata.getString(alldata.getColumnIndex(DBIDCOLNAME)));
}
alldata.close();
db.close();
return rv;
}
}
最后活动( MainActivity.java
): -
public class MainActivity extends AppCompatActivity {
ListView lv;
ArrayList<String> names = new ArrayList<>();
ArrayList<String> ids = new ArrayList<>();
ArrayAdapter adapter;
dataKasper dbhelper = new dataKasper(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) this.findViewById(R.id.listview);
if (dbhelper.getAllRowCount() < 1) {
dbhelper.insertRow("Fred");
dbhelper.insertRow("Bert");
dbhelper.insertRow("Harry");
dbhelper.insertRow("Mary");
dbhelper.insertRow("Anne");
dbhelper.insertRow("Fred"); // DUPLICATE NAME but different ID
dbhelper.insertRow("Ronald");
dbhelper.insertRow("Bert"); // DUPLICATE NAME
dbhelper.insertRow("Tom");
dbhelper.insertRow("Mike");
}
names = dbhelper.getAllNames();
ids = dbhelper.getAllIDS();
adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,android.R.id.text1,names);
lv.setAdapter(adapter);
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
// Get the associated ID according to the position
dbhelper.deleteData(Long.parseLong(ids.get(i)));
names.remove(i);
ids.remove(i);
adapter.notifyDataSetChanged();
return true;
}
});
}
}
LongClick侦听器中的重要/相关方面。
a)要删除的行的ID是通过访问ids ArrayList获得的,这些元素与名称ArrayList中的相应元素匹配。即,ids ArrayList的元素10将是相应名称的id(这可以处理重复的名称)。
b)在调用适配器notifyDataSetChanged
之前,ArrayLists与数据库中的数据对齐。即使用行names.remove(i);
和ids.remove(i);
删除相应的元素(注意!这将无法处理删除失败)。
请注意!理想情况下, ID 列应命名为 _id (CursorAdapters需要 _id 列,这是我个人使用的。)
适应上述内容以使用适配器应该相对简单。
这里的代码利用Cursor和Array适配器以及两个ListView(每个一个),这样你就可以比较两个方法: -
布局(使用第二个Listview): -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="mjt.so44730629.MainActivity">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
</ListView>
<ListView
android:id="@+id/listview2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
</ListView>
</LinearLayout>
dataKasper DBHelper(现在使用 _id 而不是ID): -
public class dataKasper extends SQLiteOpenHelper {
public final static String DBDATABASENAME = "kasper";
public final static int DBVERSION = 1;
public final static String DBTABLENAME = "Table_N";
public final static String DBIDCOLNAME = "_id";
public final static String DBNAMECOLNAME = "Name";
public final static String DBCREATESQL = "CREATE TABLE " +
DBTABLENAME + "(" +
DBIDCOLNAME + " INTEGER PRIMARY KEY," +
DBNAMECOLNAME + " TEXT" +
");";
public final static String DBORDERBYID = DBIDCOLNAME;
private int tcount;
public dataKasper(Context context) {
super(context,DBDATABASENAME,null,DBVERSION);
tcount = 0;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DBCREATESQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int newversion, int oldversion) {
}
public void deleteData(long id) {
SQLiteDatabase db = this.getWritableDatabase();
String whereclause = DBIDCOLNAME + "=?";
String[] whereargs = new String[]{Long.toString(id)};
db.delete(DBTABLENAME,whereclause,whereargs);
db.close();
}
public void deleteDataByName(String Name) {
SQLiteDatabase db = getWritableDatabase();
String whereclause = DBNAMECOLNAME + "=?";
String[] whereargs = new String[]{Name};
db.delete(DBTABLENAME,whereclause,whereargs);
db.close();
}
public Cursor getAllData() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor rv = db.query(DBTABLENAME,null,null,null,null,null,DBORDERBYID);
tcount = rv.getCount();
return rv;
}
public int getAllRowCount() {
SQLiteDatabase db = getReadableDatabase();
Cursor allrows = db.query(DBTABLENAME,null,null,null,null,null,null);
int rv = allrows.getCount();
allrows.close();
db.close();
return rv;
}
public void insertRow(String Name) {
SQLiteDatabase db = getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(DBNAMECOLNAME,Name);
db.insert(DBTABLENAME,null,cv);
db.close();
}
public ArrayList<String> getAllNames() {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<String> rv = new ArrayList<>();
Cursor alldata = getAllData();
while (alldata.moveToNext()) {
rv.add(alldata.getString(alldata.getColumnIndex(DBNAMECOLNAME)));
}
alldata.close();
db.close();
return rv;
}
public ArrayList<String> getAllIDS() {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<String> rv = new ArrayList<>();
Cursor alldata = getAllData();
while (alldata.moveToNext()) {
rv.add(alldata.getString(alldata.getColumnIndex(DBIDCOLNAME)));
}
alldata.close();
db.close();
return rv;
}
}
最后新的活动(当然你通常不会同时拥有): -
public class MainActivity extends AppCompatActivity {
ListView lv;
ListView lv2;
ArrayList<String> names = new ArrayList<>();
ArrayList<String> ids = new ArrayList<>();
ArrayAdapter adapter;
dataKasper dbhelper = new dataKasper(this);
SimpleCursorAdapter sca;
Cursor cursor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) this.findViewById(R.id.listview);
lv2 = (ListView) this.findViewById(R.id.listview2);
if (dbhelper.getAllRowCount() < 1) {
dbhelper.insertRow("Fred");
dbhelper.insertRow("Bert");
dbhelper.insertRow("Harry");
dbhelper.insertRow("Mary");
dbhelper.insertRow("Anne");
dbhelper.insertRow("Fred"); // DUPLICATE NAME but different ID
dbhelper.insertRow("Ronald");
dbhelper.insertRow("Bert"); // DUPLICATE NAME
dbhelper.insertRow("Tom");
dbhelper.insertRow("Mike");
}
names = dbhelper.getAllNames();
ids = dbhelper.getAllIDS();
adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,android.R.id.text1,names);
lv.setAdapter(adapter);
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
// Get the associated ID according to the position
dbhelper.deleteData(Long.parseLong(ids.get(i)));
names.remove(i);
ids.remove(i);
adapter.notifyDataSetChanged();
return true;
}
});
cursor = dbhelper.getAllData();
String[] fromcolumns = new String[]{dataKasper.DBNAMECOLNAME};
int[] toviews = new int[]{android.R.id.text1};
sca = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
cursor,
fromcolumns,
toviews,1);
lv2.setAdapter(sca);
lv2.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
dbhelper.deleteData(l);
cursor = dbhelper.getAllData();
sca.swapCursor(cursor);
return true;
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
cursor.close();
}
}
请注意!活动结束时onDestroy
关闭光标。游标应该一直关闭。