Как добавить новый столбец в базу данных Android SQLite?
У меня одна проблема с Android SQLite
база данных.
У меня есть одна таблица, которая содержит одно поле.StudentFname, и это приложение работает нормально с Android 2.3.1, и теперь, если я добавляю другое поле, мое приложение не работает должным образом.
Может ли кто-нибудь помочь мне, кто знает базу данных очень хорошо,
13 ответов
Ты можешь использовать ALTER TABLE
функционировать на вашем onUpgrade()
метод, как это:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// If you need to add a column
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE foo ADD COLUMN new_column INTEGER DEFAULT 0");
}
}
Очевидно, что SQLite будет отличаться в зависимости от определения столбца.
Я наткнулся на эту ветку, когда мне понадобилась помощь в моем собственном приложении, но я увидел проблемы со многими ответами. Я бы порекомендовал сделать следующее:
private static final String DATABASE_ALTER_TEAM_1 = "ALTER TABLE "
+ TABLE_TEAM + " ADD COLUMN " + COLUMN_COACH + " string;";
private static final String DATABASE_ALTER_TEAM_2 = "ALTER TABLE "
+ TABLE_TEAM + " ADD COLUMN " + COLUMN_STADIUM + " string;";
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
db.execSQL(DATABASE_ALTER_TEAM_1);
}
if (oldVersion < 3) {
db.execSQL(DATABASE_ALTER_TEAM_2);
}
}
Вы хотите убедиться, что код будет работать, когда пользователи обновят более 1 версии, и чтобы оператор обновления выполнял только то обновление, которое ему необходимо. Подробнее об этом читайте в этом блоге.
Самый простой способ сделать это - добавить SQL to the onUpgrade()
метод в вашем SQLiteOpenHelper class
, Что-то вроде:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// If you need to add a new column
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE student ADD COLUMN student_rollno INTEGER DEFAULT 0");
}
}
Возможно, немного более элегантный подход с использованием switch вместо if / then позволит перейти с любой схемы на самую последнюю схему...
Вот также хорошая страница о синтаксисе для изменения таблицы: http://alvinalexander.com/android/sqlite-alter-table-syntax-examples
public static final String TABLE_TEAM = "team";
public static final String COLUMN_COACH = "coach";
public static final String COLUMN_STADIUM = "stadium";
private static final String DATABASE_ALTER_TEAM_TO_V2 = "ALTER TABLE "
+ TABLE_TEAM + " ADD COLUMN " + COLUMN_COACH + " TEXT;";
private static final String DATABASE_ALTER_TEAM_TO_V3 = "ALTER TABLE "
+ TABLE_TEAM + " ADD COLUMN " + COLUMN_STADIUM + " TEXT;";
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion)
{
case 1:
//upgrade from version 1 to 2
db.execSQL(DATABASE_ALTER_TEAM_TO_V2);
case 2:
//upgrade from version 2 to 3
db.execSQL(DATABASE_ALTER_TEAM_TO_V3);
//and so on.. do not add breaks so that switch will
//start at oldVersion, and run straight through to the latest
}
}
Я сделал следующий подход, он решен для меня
если версия БД: 6
Ex : There is a table with 5 columns
При обновлении до: 7 (я добавляю 1 новый столбец в 3 таблицы)
1. We need to add the columns when creating a table
2. onUpgrade method:
if (oldVersion < 7)
{
db.execSQL(DATABASE_ALTER_ADD_PAPER_PAID);
db.execSQL(DATABASE_ALTER_LAST_UPLOADED);
db.execSQL(DATABASE_ALTER_PAPER_LABEL);
}
Где: "DATABASE_ALTER_ADD_PAPER_PAID" - это запрос.
EX: public static final String DATABASE_ALTER_ADD_PAPER_PAID = "ALTER TABLE "
+ TableConstants.MY_PAPERS_TABLE + " ADD COLUMN " + COLUMN_PAPER_PAID + " TEXT;";
После двух вышеуказанных операций он будет работать нормально для нового пользователя установки и обновления приложения
@Aamirkhan.i я думаю, что вы бы решили проблему, которую вы упомянули в комментариях давным-давно. Я думаю, вы не увеличили версию базы данных. или же ответы здесь просты. Я пишу это, потому что это может помочь любому, кто не увеличил или не изменил свой номер версии базы данных, когда они изменяют таблицу.
Я думаю, что мы не должны проверять такое состояние
if (newVersion > oldVersion) {
}
потому что если мы используем это, это означает, что каждый раз, когда мы увеличиваем версию базы данных, вызывается onUpdrade() и условие будет истинным, поэтому мы должны проверять вот так
if(oldVersion==1)
{
}
поэтому в этом случае, если старая версия равна 2, условие будет ложным, и пользователь со старой версией 2 не будет обновлять базу данных (которую пользователь хочет только для версии 1), потому что для этих пользователей база данных уже обновлена.
Сначала увеличьте номер версии базы данных. а затем в
onUpgrade
метод, вы можете проверить, существует ли уже столбец, если нет, то только добавьте столбец
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(!existsColumnInTable(db, TABLE_NAME, COLUMN_NAME)){
db.execSQL("ALTER TABLE foo ADD COLUMN COLUMN_NAME INTEGER DEFAULT 0");
}
}
private boolean existsColumnInTable(SQLiteDatabase inDatabase, String inTable, String columnToCheck) {
Cursor cursor = null;
try {
// Query 1 row
cursor = inDatabase.rawQuery("SELECT * FROM " + inTable + " LIMIT 0", null);
// getColumnIndex() gives us the index (0 to ...) of the column - otherwise we get a -1
if (cursor.getColumnIndex(columnToCheck) != -1)
return true;
else
return false;
} catch (Exception Exp) {
return false;
} finally {
if (cursor != null) cursor.close();
}
}
этот метод извлекается из этой ссылки Проверка наличия столбца в базе данных приложения в Android
Просто измените свой код
private final int DATABASE_VERSION = 1;
в
приватная статическая final int DATABASE_VERSION =2;
Чтобы добавить новый столбец в таблицу, вам нужно использовать ALTER
, В Android вы можете добавить новый столбец внутри onUpgrade()
,
Вы можете быть удивлены, как onUpgrade()
добавит новый столбец?
Когда вы реализуете подкласс SQLiteOpenHelper
Вам нужно вызвать конструктор суперкласса: super(context, DB_NAME, null, 1);
в вашем конструкторе класса. Там я прошел 1
для версии.
Когда я сменил версию 1
выше (2
или больше), onUpgrade()
будет вызван. И выполнить модификации SQL, которые я намерен сделать. Мой конструктор класса после изменения версии:
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 2);//version changed from 1 to 2
}
Проверка модификаций SQL выполняется следующим образом: конструктор суперкласса сравнивает версию хранимого файла базы данных SQLite с версией, которую я передал super()
, Если эти (предыдущие и сейчас) номера версий отличаются onUpgrade()
вызывается.
Код должен выглядеть так:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// add new columns to migrate to version 2
if (oldVersion < 2) {
db.execSQL("ALTER TABLE " + TABLE_NAME + "ADD COLUMN school VARCHAR(250)");
}
// add new columns to migrate to version 3
if (oldVersion < 3) {
db.execSQL("ALTER TABLE " + TABLE_NAME + "ADD COLUMN age INTEGER");
}
}
Я наткнулся на ссылку при поиске той же проблемы. Это объясняет, как использовать обновление. https://thebhwgroup.com/blog/how-android-sqlite-onupgrade
это объясняет, почему использовать этот код ниже
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
db.execSQL(DATABASE_ALTER_TEAM_1);
}
if (oldVersion < 3) {
db.execSQL(DATABASE_ALTER_TEAM_2);
}
}
Самый простой способ создать новый столбец в таблице - добавить SQL-код в метод onUpgrade() класса SQLiteOpenHelper. Подобно:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
db.execSQL(SQL_MY_TABLE);
case 2:
db.execSQL("ALTER TABLE myTable ADD COLUMN myNewColumn TEXT");
}
}
Не заметил ответов, ищите наличие столбца:
Cursor cursor = database.rawQuery("SELECT * FROM " + MY_TABLE, null);
int columnIndex = cursor.getColumnIndex(MY_NEW_COLUMN);
if (columnIndex < 0) {
database.execSQL("ALTER TABLE " + MY_TABLE + " ADD COLUMN " + MY_NEW_COLUMN + " TEXT");
}