Хорошо, перед тем, как столкнуться с более крупными проблемами, вы должны знать, что SQLite ограничен командой ALTER TABLE, она позволяет add
и rename
только удаление / удаление, что выполняется при воссоздании таблицы.
Вы всегда должны иметь под рукой новый запрос на создание таблицы и использовать его для обновления и передачи любых существующих данных. Обратите внимание: что методы onUpgrade запускают один для вашего вспомогательного объекта sqlite, и вам нужно обработать все таблицы в нем.
Итак, что рекомендуется при обновлении:
- BeginTransaction
- запустить создание таблицы с помощью
if not exists
(мы проводим обновление, поэтому таблица может еще не существовать, она не сможет изменить и удалить)
- внести в список существующие столбцы
List<String> columns = DBUtils.GetColumns(db, TableName);
- резервная таблица (
ALTER table " + TableName + " RENAME TO 'temp_" + TableName
)
- создать новую таблицу (новейшая схема создания таблицы)
- получить пересечение с новыми столбцами, на этот раз столбцы взяты из обновленной таблицы (
columns.retainAll(DBUtils.GetColumns(db, TableName));
)
- восстановить данные (
String cols = StringUtils.join(columns, ",");
db.execSQL(String.format(
"INSERT INTO %s (%s) SELECT %s from temp_%s",
TableName, cols, cols, TableName));
)
- удалить таблицу резервных копий (
DROP table 'temp_" + TableName
)
- setTransactionSuccessful
(Это не обрабатывает понижение таблицы, если вы переименуете столбец, вы не передадите существующие данные, поскольку имена столбцов не совпадают).
.
public static List<String> GetColumns(SQLiteDatabase db, String tableName) {
List<String> ar = null;
Cursor c = null;
try {
c = db.rawQuery("select * from " + tableName + " limit 1", null);
if (c != null) {
ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
}
} catch (Exception e) {
Log.v(tableName, e.getMessage(), e);
e.printStackTrace();
} finally {
if (c != null)
c.close();
}
return ar;
}
public static String join(List<String> list, String delim) {
StringBuilder buf = new StringBuilder();
int num = list.size();
for (int i = 0; i < num; i++) {
if (i != 0)
buf.append(delim);
buf.append((String) list.get(i));
}
return buf.toString();
}