SQLite:删除后创建新项目时 ID 错误
SQLite : Wrong ID when i create a new item after an elimination
我创建了字段 id autoincrement
,当我创建一个项目时没有问题。当我删除一个项目时,问题就开始了:只有当数据库中所有项目的 ID 都低于我要删除的项目时,该项目才会被正确删除。
这是一个例子:
id item
-----------------
1 swim
2 tennis
3 football
4 baseball
当我删除 baseball 时一切正常,但如果我在删除 baseball 后创建一个新项目,它的 id = 5
例如:
id item
------------------
1 swim
2 tennis
3 football
5 rugby
所以,现在删除橄榄球需要 2 次点击 (而不是一次)我将图片变成可点击的 recyclerview 才能删除该项目。发生这种情况是因为 rugby 下的第一个元素的 id = 3 而不是 4。
另一个例子:在数据库中我只有一个 id = 18 的项目,要删除它我必须点击 18 次因为 id 在它变为 1 时递减然后被删除。
我不知道如何让自动增量列 id 从最高 id 重新开始自动增量到数据库中,或者如果没有项目让它从 1 重新开始。
这是delete
(我使用变量j因为位置从0开始):
public void deleteEntry(int position) {
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
int j = position + 1;
sqLiteDatabase.execSQL("DELETE FROM " + SportEntry.TABLE_NAME + " WHERE " +
SportEntry._ID + " = " + j + ";");
sqLiteDatabase.execSQL("UPDATE " + SportEntry.TABLE_NAME + " SET " + SportEntry._ID + " = " +
SportEntry._ID + " -1 " + " WHERE " + SportEntry._ID + " > " + j + ";");
}
这是 dbHelper 中的 onCreate class:
public void onCreate(SQLiteDatabase db) {
String SQL_CREATE_SPORT_TABLE = "CREATE TABLE " + TABLE_NAME + "("
+ SportEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ SportEntry.COLUMN_ATTIVITA + " TEXT NOT NULL);";
db.execSQL(SQL_CREATE_SPORT_TABLE);
}
这是合同class:
public final class SportContract {
private SportContract(){}
public static final class SportEntry implements BaseColumns {
public static final String TABLE_NAME = "sport";
public static final String _ID = BaseColumns._ID;
public static final String COLUMN_ATTIVITA = "Attivita";
}
}
When I delete baseball is all ok, but if I create a new item after the
elimination of baseball it has the id = 5
根据数据库,这是正确的流程,因为 id 设置为自动增量,而且它是主键。
So, now the elimination of rugby needs 2 clicks (instead of one) on
the image I made clickable into a clickable recyclerview in order to
delete the item.
这不是处理单击事件以访问 recyclerview 上的特定项目的正确方法。如果你继续这样做,那么当记录达到 200 项时,你将无法继续单击 200 次。
为了更好地做到这一点,使用每条记录的 id 作为 where 子句来获取所有对应的记录并显示在新的 activity.
此代码允许我获取所选项目的正确 ID:
进入DbHelper,就是函数delete
:
public void deleteEntry(int position) {
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
sqLiteDatabase.execSQL("DELETE FROM " + SportEntry.TABLE_NAME + " WHERE " +
SportEntry._ID + " = " + position + ";");
sqLiteDatabase.execSQL("UPDATE " + SportEntry.TABLE_NAME + " SET " + SportEntry._ID + " = " +
SportEntry._ID + " -1 " + " WHERE " + SportEntry._ID + " > " + position + ";");
}
OnDeleteClick
函数进入主 activity (当我点击与项目对应的图像进入 recyclerview 允许我删除项目):
@Override
public void onDeleteClick (int position) {
int x = ReadID(position);
removeItem(x);
}
removeItem
函数进入主activity:
public void removeItem(int position) {
mDbHelper.deleteEntry(position);
mAdapter.swapCursor(mDbHelper.getAllItems());
}
这是主要 class 的功能,它允许我获取正确的 ID:
public int ReadID(int position){
mDbHelper = new SportDbHelper(this);
SQLiteDatabase db = mDbHelper.getReadableDatabase();
String[] projection = {BaseColumns._ID,
};
String sortOrder = SportEntry._ID + " ASC";
Cursor cursor = db.query(
SportEntry.TABLE_NAME, // The table to query
projection, // The array of columns to return (null to get all)
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // null if you don't want to group the rows
null, // null if you don't want filter by row groups
sortOrder // the order
);
try {
int idColumnIndex = cursor.getColumnIndex(SportEntry._ID);
int currentID = 0;
int cg=0;
while ((cursor.moveToNext() == true) && (cg != (position + 1))) {
currentID = cursor.getInt(idColumnIndex);
cg ++;
}
return currentID;
} finally {
cursor.close();
}
}
为了完整起见,这是 getAllItems()
函数到 DbHelper
class:
public Cursor getAllItems() {
SQLiteDatabase db = getReadableDatabase();
return db.query(
SportEntry.TABLE_NAME,
null,
null,
null,
null,
null,
null
);
}
我创建了字段 id autoincrement
,当我创建一个项目时没有问题。当我删除一个项目时,问题就开始了:只有当数据库中所有项目的 ID 都低于我要删除的项目时,该项目才会被正确删除。
这是一个例子:
id item
-----------------
1 swim
2 tennis
3 football
4 baseball
当我删除 baseball 时一切正常,但如果我在删除 baseball 后创建一个新项目,它的 id = 5
例如:
id item
------------------
1 swim
2 tennis
3 football
5 rugby
所以,现在删除橄榄球需要 2 次点击 (而不是一次)我将图片变成可点击的 recyclerview 才能删除该项目。发生这种情况是因为 rugby 下的第一个元素的 id = 3 而不是 4。
另一个例子:在数据库中我只有一个 id = 18 的项目,要删除它我必须点击 18 次因为 id 在它变为 1 时递减然后被删除。
我不知道如何让自动增量列 id 从最高 id 重新开始自动增量到数据库中,或者如果没有项目让它从 1 重新开始。
这是delete
(我使用变量j因为位置从0开始):
public void deleteEntry(int position) {
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
int j = position + 1;
sqLiteDatabase.execSQL("DELETE FROM " + SportEntry.TABLE_NAME + " WHERE " +
SportEntry._ID + " = " + j + ";");
sqLiteDatabase.execSQL("UPDATE " + SportEntry.TABLE_NAME + " SET " + SportEntry._ID + " = " +
SportEntry._ID + " -1 " + " WHERE " + SportEntry._ID + " > " + j + ";");
}
这是 dbHelper 中的 onCreate class:
public void onCreate(SQLiteDatabase db) {
String SQL_CREATE_SPORT_TABLE = "CREATE TABLE " + TABLE_NAME + "("
+ SportEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ SportEntry.COLUMN_ATTIVITA + " TEXT NOT NULL);";
db.execSQL(SQL_CREATE_SPORT_TABLE);
}
这是合同class:
public final class SportContract {
private SportContract(){}
public static final class SportEntry implements BaseColumns {
public static final String TABLE_NAME = "sport";
public static final String _ID = BaseColumns._ID;
public static final String COLUMN_ATTIVITA = "Attivita";
}
}
When I delete baseball is all ok, but if I create a new item after the elimination of baseball it has the id = 5
根据数据库,这是正确的流程,因为 id 设置为自动增量,而且它是主键。
So, now the elimination of rugby needs 2 clicks (instead of one) on the image I made clickable into a clickable recyclerview in order to delete the item.
这不是处理单击事件以访问 recyclerview 上的特定项目的正确方法。如果你继续这样做,那么当记录达到 200 项时,你将无法继续单击 200 次。
为了更好地做到这一点,使用每条记录的 id 作为 where 子句来获取所有对应的记录并显示在新的 activity.
此代码允许我获取所选项目的正确 ID:
进入DbHelper,就是函数delete
:
public void deleteEntry(int position) {
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
sqLiteDatabase.execSQL("DELETE FROM " + SportEntry.TABLE_NAME + " WHERE " +
SportEntry._ID + " = " + position + ";");
sqLiteDatabase.execSQL("UPDATE " + SportEntry.TABLE_NAME + " SET " + SportEntry._ID + " = " +
SportEntry._ID + " -1 " + " WHERE " + SportEntry._ID + " > " + position + ";");
}
OnDeleteClick
函数进入主 activity (当我点击与项目对应的图像进入 recyclerview 允许我删除项目):
@Override
public void onDeleteClick (int position) {
int x = ReadID(position);
removeItem(x);
}
removeItem
函数进入主activity:
public void removeItem(int position) {
mDbHelper.deleteEntry(position);
mAdapter.swapCursor(mDbHelper.getAllItems());
}
这是主要 class 的功能,它允许我获取正确的 ID:
public int ReadID(int position){
mDbHelper = new SportDbHelper(this);
SQLiteDatabase db = mDbHelper.getReadableDatabase();
String[] projection = {BaseColumns._ID,
};
String sortOrder = SportEntry._ID + " ASC";
Cursor cursor = db.query(
SportEntry.TABLE_NAME, // The table to query
projection, // The array of columns to return (null to get all)
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // null if you don't want to group the rows
null, // null if you don't want filter by row groups
sortOrder // the order
);
try {
int idColumnIndex = cursor.getColumnIndex(SportEntry._ID);
int currentID = 0;
int cg=0;
while ((cursor.moveToNext() == true) && (cg != (position + 1))) {
currentID = cursor.getInt(idColumnIndex);
cg ++;
}
return currentID;
} finally {
cursor.close();
}
}
为了完整起见,这是 getAllItems()
函数到 DbHelper
class:
public Cursor getAllItems() {
SQLiteDatabase db = getReadableDatabase();
return db.query(
SportEntry.TABLE_NAME,
null,
null,
null,
null,
null,
null
);
}