Способ работы автоинкремента заключается в том, что при определении нового значения используются 2 значения: -
1 добавляется к большему значению.
Для сброса теоретически вы должны удалить все строки из таблицы и удалить соответствующую строку из таблицы sqlite_sequence .
Однако помещение защищает системные таблицы.Итак, короче говоря, кажется, что нет возможности использовать пространство, чтобы сделать последнее и, следовательно, проблема. Вот ответ, это пример, который делает выше НО , он должен быть запущен за пределами (до) комнаты и поэтому ограничен.
- Примечание в ответе есть дополнительный код, который используется для начала нумерации с 0 (триггер).
Однако в отношении переполнениятогда это в принципе крайне маловероятно в соответствии с: -
Максимальное количество строк в таблице
Теоретическое максимальное количество строк в таблице равно 2 в степени 64 (18446744073709551616 или около 1,8e + 19).Этот предел недоступен, так как сначала будет достигнут максимальный размер базы данных в 140 терабайт.База данных объемом 140 терабайт может содержать не более 1e + 13 строк, и только в том случае, если индексов нет и каждая строка содержит очень мало данных. Пределы в SQLite
С автоинкрементом это 2 к степени 63 (9,223,372,036,854,775,808) (без автоинкремента вы можете использовать отрицательные значения (Java), так что вы можете использовать64-й бит, следовательно, торектический максимум) как таковое ограничение скорее всего будет связано с емкостью диска, а не с наивысшим достигаемым идентификатором.
Дополнительно
После некоторой игры, следующее сбрасываетПоследовательность, в то время как Room имеет базу данных.
То есть следующая сборка базы данных Room вставляет две строки, сбрасывает последовательность (включая удаление недавно добавленных строк)
- , открывая базу данных какстандартная база данных SQLite
- Обратите внимание на использование как OPENREADWRITE, так и ENABLEWRITEAHEADLOGGING
- (если не последнее, то предупреждающее сообщение о том, что WAL не может быть отключено, так как база данных открыта, так что это простооткрывает его в режиме WAL)
- удаление существующих строк в таблице и
- удалениеизвлекая соответствующую строку из sqlite_sequence и, наконец,
- закрывая эту другую базу данных.
: -
public class MainActivity extends AppCompatActivity {
public static final String DBNAME = "mydatabase";
public static final String MYTABLENAME = "mytable";
MyDatabase mydb,mydb2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mydb = Room.databaseBuilder(this,MyDatabase.class,DBNAME).allowMainThreadQueries().build();
MyTableDAO mytabledao = mydb.getMyTableDAO();
MyTable mt1 = new MyTable();
mt1.setName("Test001");
mytabledao.insert(mt1);
MyTable mt2 = new MyTable();
mt2.setName("Test002");
mytabledao.insert(mt2);
for (MyTable mt: mytabledao.getAllMyTables()) {
Log.d("MYTABLEROW","ID=" + String.valueOf(mt.getId()) + " Name=" + mt.getName());
}
/*
while (mydb.isOpen()) {
mydb.close();
}
Ouch if used :-
E/ROOM: Invalidation tracker is initialized twice :/. (ignored)
E/ROOM: Cannot run invalidation tracker. Is the db closed?
java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
*/
resetSequencedTable(MYTABLENAME);
//mydb2 = Room.databaseBuilder(this,MyDatabase.class,DBNAME).allowMainThreadQueries().build(); // No Good
/*
Works even though :-
05-12 12:31:40.112 28585-28585/? D/MYTABLEROW: ID=1 Name=Test001
05-12 12:31:40.112 28585-28585/? D/MYTABLEROW: ID=2 Name=Test002
05-12 12:31:40.114 28585-28585/? E/SQLiteLog: (5) statement aborts at 2: [PRAGMA journal_mode=PERSIST]
05-12 12:31:40.115 28585-28585/? W/SQLiteConnection: Could not change the database journal mode of '/data/user/0/soa.myapplication/databases/mydatabase' from 'wal' to 'PERSIST' because the database is locked. This usually means that there are other open connections to the database which prevents the database from enabling or disabling write-ahead logging mode. Proceeding without changing the journal mode.
05-12 12:31:40.126 28585-28585/? D/MYTABLEROW: ID=1 Name=Test003
05-12 12:31:40.126 28585-28585/? D/MYTABLEROW: ID=2 Name=Test004
*/
for (MyTable mt: mytabledao.getAllMyTables()) {
Log.d("MYTABLEROW","ID=" + String.valueOf(mt.getId()) + " Name=" + mt.getName());
}
MyTable mt3 = new MyTable();
mt3.setName("Test003");
mytabledao.insert(mt3);
MyTable mt4 = new MyTable();
mt4.setName("Test004");
mytabledao.insert(mt4);
for (MyTable mt: mytabledao.getAllMyTables()) {
Log.d("MYTABLEROW","ID=" + String.valueOf(mt.getId()) + " Name=" + mt.getName());
}
}
private void resetSequencedTable(String table) {
Log.d("RESETSEQ","Initiating sequence reset");
SQLiteDatabase db = SQLiteDatabase.openDatabase(this.getDatabasePath(DBNAME).toString(),null,SQLiteDatabase.OPEN_READWRITE | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING);
db.delete(table,null,null);
String whereclause = "name=?";
String[] whereargs = new String[]{table};
db.delete("sqlite_sequence",whereclause,whereargs);
db.close();
Log.d("RESETSEQ", "Terminating sequence reset");
}
}
Объект для таблицы: -
@Entity(tableName = MainActivity.MYTABLENAME)
public class MyTable {
@PrimaryKey(autoGenerate = true)
private long id;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}