Android SQLite在删除后更改rowids
我在使用android程序处理sqlite数据库时遇到问题。 我正在制作一个小部件,它有一个我希望能够滚动浏览的列表,因此当我单击“下一步”按钮时,它将显示数据库中的下一行 在我从数据库中删除某些内容并且我的rowid缺少数字之前,这一切都很正常。我将rowids设置为AUTOINCREMENT,但是在删除一些数据后,我丢失了一些数字,当我尝试滚动这些数字时,返回了一个错误 我只是想知道,在删除一行之后,是否有其他方法将rowid更改为顺序。或者是否有更好的方法在不参考rowid的情况下滚动每一行 编辑:这是我的“下一步”活动的代码 这看起来很粗糙,但我在想有没有办法 cursor.moveToNext(); 在我的数据库类中获取下一个数字 这是我的数据库类顺便说一句 私有静态类DbHelper扩展了SQLiteOpenHelper{Android SQLite在删除后更改rowids,android,sqlite,Android,Sqlite,我在使用android程序处理sqlite数据库时遇到问题。 我正在制作一个小部件,它有一个我希望能够滚动浏览的列表,因此当我单击“下一步”按钮时,它将显示数据库中的下一行 在我从数据库中删除某些内容并且我的rowid缺少数字之前,这一切都很正常。我将rowids设置为AUTOINCREMENT,但是在删除一些数据后,我丢失了一些数字,当我尝试滚动这些数字时,返回了一个错误 我只是想知道,在删除一行之后,是否有其他方法将rowid更改为顺序。或者是否有更好的方法在不参考rowid的情况下滚动每一
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// execute some SQL code
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + KEY_ROWID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, "
//+ KEY_NUM + " INTEGER NOT NULL, "
+ KEY_WORD + " TEXT NOT NULL, "
+ KEY_MEANING + " TEXT NOT NULL);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
public FlashDataBase(Context c) {
myContext = c;
}
// open our db
public FlashDataBase open() throws SQLException {
myHelper = new DbHelper(myContext);
myDatabase = myHelper.getWritableDatabase();
return this;
}
// and this closes it
public void close() {
myHelper.close();
}
public long createMethod(String word, String meaning) {
ContentValues cv = new ContentValues();
//cv.put(KEY_NUM, num);
cv.put(KEY_WORD, word);
cv.put(KEY_MEANING, meaning);
// and put these strings into our database
// inserts the cv into the table
return myDatabase.insert(DATABASE_TABLE, null, cv);
}
public String getData() {
String[] columns = new String[] { KEY_ROWID, KEY_WORD, KEY_MEANING };
// set a cursor to read the info
Cursor c = myDatabase.query(DATABASE_TABLE, columns, null, null, null,
null, null);
String result = "";
// these ints are the same as getWord's method
// in other words, 0 1 and 2 respectively
int iWord = c.getColumnIndex(KEY_WORD);
int iMeaning = c.getColumnIndex(KEY_MEANING);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
result += c.getInt(0) + " " + c.getString(iWord) + " " + c.getString(iMeaning) + "\n";
}
return result;
}
public String getWord(long l) {
String[] columns = new String[] { KEY_ROWID, KEY_WORD, KEY_MEANING };
Cursor c = myDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "="
+ l, null, null, null, null);
if (c != null) {
// since we set KEY_ROWID to itself plus Long (l), then the
// moveToFirst starts at L (l) ^as seen above
c.moveToFirst();
// thats a number 1 not letter l below
// which is the second column, aka int iWord from the getData class
String word = c.getString(1);
return word;
}
return null;
}
public String getMeaning(long l) {
String[] columns = new String[] { KEY_ROWID, KEY_WORD, KEY_MEANING };
Cursor c = myDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "="
+ l, null, null, null, null);
if (c != null) {
// since we set KEY_ROWID to itself plus Long (l), then the
// moveToFirst starts at L (l) ^as seen above
c.moveToFirst();
// thats a number 2 below
// which is the second column, aka int iWord from the getData class
String meaning = c.getString(2);
return meaning;
}
return null;
}
public int getNumber() {
String[] columns = new String[] { KEY_ROWID, KEY_WORD, KEY_MEANING };
// set a cursor to read the info
Cursor c = myDatabase.query(DATABASE_TABLE, columns, null, null, null,
null, null);
int result = 0;
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
result++;
}
return result;
}
也谢谢你的帮助
*最终编辑:
我的理解与别人告诉我的略有不同;我将计数保留在一个共享整数值中,如果超过行的总数,该值将重置,并在数据库类本身中使用c.moveToNext()而不是共享整数进行循环,如下所示:
public String getWord(long l) {
String[] columns = new String[] { KEY_ROWID, KEY_WORD, KEY_MEANING };
Cursor c = myDatabase.query(DATABASE_TABLE, columns, KEY_ROWID, null, null, null, null);
String result;
c.moveToFirst();
for(int i=1; i<=l; i++){
if(c.isLast()){
c.moveToFirst();
result = c.getString(1);
return result;
}
c.moveToNext();
}
result = c.getString(1);
return result;
}
公共字符串getWord(长l){
String[]columns=新字符串[]{KEY\u ROWID,KEY\u WORD,KEY\u means};
游标c=myDatabase.query(数据库表、列、键ROWID、null、null、null、null);
字符串结果;
c、 moveToFirst();
对于(int i=1;iSQL在删除行后自动递增ID的工作方式将是一致的,因此使ID重新顺序的唯一方法是手动移动条目或复制行、删除表、创建新表并再次插入行
但是,您可以在SQL查询中使用LIMIT
子句来确定要获取的行数和行数。具体而言,您可以使用类似于以下内容的查询:
SELECT * FROM `your_table` LIMIT first_row_to_fetch, number_of_rows_to_fetch
例如,如果您想要10行,从第17行开始(独立于ID),您可以使用
SELECT * FROM `your_table` LIMIT 17, 10
编辑:
给定您自己的编辑,您不会执行自己的查询字符串,因此在您的情况下,您应该使用query()
方法,并为限制/偏移量
添加属性(请参阅)。
您已经在使用的query()
方法重载的字符串应该包含一个数字(这是查询的限制)或两个由逗号分隔的数字(首先是偏移量,然后是查询的限制)。实际上,这意味着
Cursor c = myDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
变成
Cursor c = myDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null, "offset,limit");
其中偏移和限制的工作方式与上面的第一个示例类似
此外,您可能希望在orderBy属性(limit属性之前的属性)中添加一些内容,这样您就知道每次的结果都是相同的。我建议为此使用KEY\u ROWID
,结果是:
Cursor c = myDatabase.query(DATABASE_TABLE, columns, null, null, null, null, KEY_ROWID, "offset,limit");
您可以使用SQLite版本的ROWID(SQLite拥有它们,但在SELECT中直接请求它们之前,无法看到它们)。它们是自动递增的。删除一些记录或记录组后,您可以执行真空;。
对于SQLiteVACUUM非常方便,因为它将完全重写数据库文件并删除碎片。所有这些都指向从SQLite表中删除数据,它实际上仍然驻留在数据库文件中,但标记为脏。因此,此方法将允许您从垃圾数据中清除数据库文件(文件大小将减小)而且还将重建ROWID序列以使其正确,并将重建索引等等。但您不应该依赖ROWID。使用您给定的实际PK列名,而不是此内置名称,并且不必注意PK值是什么,也不必担心编号序列中的间隙。PK只是一个方便的句柄,可以让您可以唯一地标识行并获取它….其中id=?
始终增加id(而不是填补空白)如果你仔细想想,这是有道理的。你应该发布你的代码,因为我相信这一点都不成问题。谢谢你的帮助。尽管我的最终方法不同,但从长远来看,它帮助我理解了这一点。非常欢迎你。我想我个人的方法是获取所有条目并将它们放入数组或其他什么东西中,如果没有的话太多了。但我很高兴我能帮上忙。
Cursor c = myDatabase.query(DATABASE_TABLE, columns, null, null, null, null, KEY_ROWID, "offset,limit");