Как добавить новый столбец в базу данных Android SQLite?

83

У меня одна проблема с SQLiteбазой данных Android .

У меня есть одна таблица, содержащая одно поле .StudentFname, и это приложение отлично работает с Android 2.3.1, и теперь, если я добавлю еще одно поле, мое приложение не работает должным образом.

Может ли кто-нибудь помочь мне, кто очень хорошо знает базу данных,

Амир Кхан
источник

Ответы:

189

вы можете использовать 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 будет отличаться в зависимости от определения столбца.

DevYudh
источник
1
Привет! Я пробовал это, я использовал метод обновления, и внутри я также поставил запрос на изменение таблицы. но все же я не могу добавить новый столбец в базу данных ... но я, когда я пишу запрос, чтобы добавить новый столбец и переименовать имя базы данных и таблицы, чем я могу добавить новый столбец .. но с помощью метода изменения таблицы я не могу этого сделать .. переименование базы данных и таблицы не является желаемой задачей .. он должен работать с изменением table .. все же я не могу сделать это с помощью метода alter table ..
Aamirkhan 05
@NagarjunaReddy, извините за поздний ответ. вы можете использовать этот метод db.execSQL ("UPDATE table SET key = key + 1 WHERE name =?", new String [] {name});
DevYudh
3
Не забудьте увеличить версию базы данных, иначе onUpgrade () не будет вызываться. Увеличьте номер версии в приведенном ниже коде, который будет присутствовать в конструкторе класса, расширяющего класс SQLiteOpenHelper. super (контекст контекста, имя строки, фабрика CursorFactory, int newVersion)
appdroid
Приложение зависает, и у меня много таких сообщений в журнале cat: Пул соединений для базы данных '+ data + user + 0 + com ..._ db' не смог предоставить соединение с потоком 1 (основным) с флагами 0x5 для. Почему это произошло?
Махди
if (newVersion > oldVersion) условие здесь не нужно, потому что оно вызывается onUpgradeтолько при выполнении этого условия, т. е. новая версия больше, чем старая версия
новичок
31

Я наткнулся на эту ветку, когда нуждался в помощи в моем собственном приложении, но обнаружил проблемы со многими ответами. Я бы порекомендовал сделать следующее:

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);
    }
}

Вы хотите убедиться, что код будет работать, когда пользователи обновят более одной версии, и что оператор обновления запускает только одно необходимое обновление. Чтобы узнать больше об этом, посетите этот блог .

PФраншиза
источник
что делать, если мы хотим создать измененный столбец со значением String по умолчанию ??
shridutt kothari
22

Самый простой способ сделать это - добавить какой-нибудь 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");
    }
}
user370305
источник
Я пробовал это, но все же я не могу добавить новый столбец с помощью метода изменения таблицы в методе обновления.
Аамирхан
Привет! Я пробовал это, я использовал метод обновления, и внутри я также поставил запрос на изменение таблицы. но все же я не могу добавить новый столбец в базу данных ... но я, когда я пишу запрос, чтобы добавить новый столбец и переименовать имя базы данных и таблицы, чем я могу добавить новый столбец .. но с помощью метода изменения таблицы я не могу этого сделать .. переименование базы данных и таблицы не является желаемой задачей .. он должен работать с изменением table .. все же я не могу сделать это с помощью метода alter table
Аамирхан
@ user370305 Должен ли я добавить новый столбец в инструкцию create tablle для новых пользователей, которые устанавливают приложение в первый раз?
Ахесанали Сутар
15

Возможно, немного более элегантный подход с использованием 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

    }

}
Эдвард Бэгби
источник
Так можно выполнить несколько обновлений. Проверяем, с какой версии!
Ricardo
Если вы перейдете с версии 1 на версию 3 напрямую (если кто-то не обновит приложение автоматически), вы не дойдете до
варианта
@ TyMarc - Да, он обновится до версий 2, затем 3. Коммутатор использует старую версию. Итак, в вашем примере старая версия - 1. Затем код будет запускать вариант 1, который обновляется с версий 1 до 2, а затем запускает вариант 2 (так как нет перерыва;), который обновляется с 2 до 3. Все в описании.
Эдвард Бэгби
4

Я проделал следующий подход, он восстановлен для меня

если версия БД: 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;";

После двух вышеуказанных операций он будет отлично работать для нового пользователя установки и пользователя обновления приложения.

sssvrock
источник
3

@ Aamirkhan.i думаю, что вы бы уже давно решили проблему, о которой упоминали в комментариях. Думаю, вы не увеличивали версию базы данных. в противном случае ответы здесь прямые. Я пишу это, потому что это может помочь любому, кто не увеличивал или не менял номер версии своей базы данных, когда они изменяют таблицу.

Дора
источник
да, изменение имени базы данных и удаление приложения, а также его повторная установка решат проблему
Аамирхан
@Aamirkhan, переместите чек к следующему ответу, чтобы более понятное решение было доступно общественности.
AlleyOOP 05
3

Я думаю, что мы не должны проверять такое условие

 if (newVersion > oldVersion) {
 }

потому что, если мы используем это, это означает, что каждый раз, когда мы увеличиваем версию базы данных, будет вызываться onUpdrade (), и условие будет истинным, поэтому мы должны проверить это

if(oldVersion==1) 
{

}

поэтому в этом случае, если старая версия равна 2, тогда условие будет ложным, и пользователь со старой версией 2 не будет обновлять базу данных (который пользователь хочет только для версии 1), потому что для этих пользователей база данных уже обновлена.

Химаншу арора
источник
1

Чтобы добавить новый столбец в таблицу, вам нужно использовать 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");
    }
}
Бласанка
источник
1

Просто измените свой код

частный финал int DATABASE_VERSION = 1;

к

частный статический финал int DATABASE_VERSION = 2;

Шахзад Ахмад
источник
0

Я наткнулся на ссылку при поиске той же проблемы. В нем объясняется, как использовать обновление. 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);
        }
    }
Ананд
источник
0

Самый простой способ создать новый столбец в таблице - это добавить некоторый 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");
    }
}
Дигвидж Борда
источник
0

сначала увеличьте номер версии базы данных. а затем в 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

новичок
источник