Jak dodać nową kolumnę do bazy danych SQLite systemu Android?

83

Mam jeden problem z SQLitebazą danych Androida .

Mam jedną tabelę, która zawiera jedno pole.StudentFname i ta aplikacja działa dobrze z Androidem 2.3.1, a teraz, jeśli dodam kolejne pole, moja aplikacja nie działa poprawnie.

Czy może mi pomóc ktoś, kto bardzo dobrze zna bazę danych,

Aamirkhan
źródło

Odpowiedzi:

189

możesz użyć ALTER TABLEfunkcji w swojej onUpgrade()metodzie, na przykład:

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

Oczywiście SQLite będzie się różnić w zależności od definicji kolumny.

DevYudh
źródło
1
cześć! Próbowałem tego użyłem w metodzie upgrade, a wewnątrz tego umieściłem również zapytanie o zmianę tabeli. ale nadal nie jestem w stanie dodać nowej kolumny do bazy danych .. ale tak, kiedy piszę zapytanie, aby dodać nową kolumnę i zmienić nazwę zarówno baza danych, jak i nazwa tabeli są w stanie dodać nową kolumnę, ale przy pomocy metody alter table nie jestem w stanie tego zrobić. zmiana nazwy bazy danych i tabeli nie jest pożądanym zadaniem .. powinno pracować z alter table..Nadal nie jestem w stanie tego zrobić za pomocą metody alter table ..
Aamirkhan
@NagarjunaReddy przepraszam za spóźnioną odpowiedź. możesz użyć tej metody db.execSQL ("UPDATE table SET key = key + 1 WHERE name =?", new String [] {name});
DevYudh
3
Nie zapomnij zwiększyć wersji bazy danych, w przeciwnym razie onUpgrade () nie zostanie wywołany. Zwiększ numer wersji w poniższym kodzie, który będzie obecny w konstruktorze klasy rozszerzającej klasę SQLiteOpenHelper. super (kontekst kontekstowy, nazwa ciągu, fabryka CursorFactory, int newVersion)
appdroid
Aplikacja zawiesza się i mam wiele takich komunikatów w dzienniku cat: Pula połączeń dla bazy danych „+ data + użytkownik + 0 + com ..._ db” nie mogła przyznać połączenia z wątkiem 1 (głównym) z flagami 0x5 dla. Dlaczego tak się stało?
Mahdi
if (newVersion > oldVersion) warunek jest tutaj niepotrzebny, ponieważ onUpgradesam jest wywoływany tylko wtedy, gdy ten warunek jest spełniony, tj. nowa wersja jest większa niż stara wersja
początkujący
31

Natknąłem się na ten wątek, gdy potrzebowałem pomocy we własnej aplikacji, ale zauważyłem problemy z wieloma odpowiedziami. Poleciłbym wykonanie następujących czynności:

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

Chcesz mieć pewność, że kod będzie działał, gdy użytkownicy zaktualizują więcej niż 1 wersję, a instrukcja aktualizacji uruchamia tylko jedno uaktualnienie, które jest potrzebne. Więcej informacji na ten temat znajdziesz na tym blogu .

PFranczyza
źródło
co zrobić, jeśli chcemy stworzyć zmienioną kolumnę z domyślną wartością String?
shridutt kothari
22

Najłatwiej to zrobić, dodając trochę SQL to the onUpgrade() metody do pliku SQLiteOpenHelper class. Coś jak:

@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
źródło
Próbowałem tego, ale nadal nie mogę dodać nowej kolumny przy użyciu metody alter table w metodzie aktualizacji.
Aamirkhan,
cześć! Próbowałem tego użyłem w metodzie aktualizacji, a wewnątrz tego umieściłem również zapytanie o zmianę tabeli. ale nadal nie jestem w stanie dodać nowej kolumny do bazy danych ... ale tak, kiedy piszę zapytanie, aby dodać nową kolumnę i zmieniono nazwę zarówno baza danych, jak i nazwa tabeli są w stanie dodać nową kolumnę, ale z pomocą metody alter table nie jestem w stanie tego zrobić. zmiana nazwy bazy danych i tabeli nie jest pożądanym zadaniem .. to powinno działać z alter table.. nadal nie jestem w stanie tego zrobić ze
zmienioną
@ user370305 Czy powinienem dodać nową kolumnę w tabeli tworzenia instrukcji tworzenia dla nowych użytkowników, którzy instalują aplikację po raz pierwszy?
Ahesanali Suthar
15

Być może nieco bardziej eleganckie podejście z użyciem przełącznika zamiast opcji if / then, które spowoduje uaktualnienie z dowolnego schematu do najnowszego schematu ...

Oto przyzwoita strona na temat składni do zmiany tabeli: 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

    }

}
Edward Bagby
źródło
To jest sposób na obsługę wielu uaktualnień. Sprawdzanie, z której wersji pochodzi!
Ricardo
Jeśli przejdziesz bezpośrednio z wersji 1 do 3 (jeśli ktoś nie zaktualizuje automatycznie aplikacji), nie dotrzesz do przypadku 2.
TyMarc
@ TyMarc - Tak, nastąpi aktualizacja do wersji 2, a następnie 3. Przełącznik korzysta ze starej wersji. W naszym przykładzie stara wersja to 1. Kod uruchomi wtedy przypadek 1, który aktualizuje z wersji 1 do 2, a następnie uruchomi przypadek 2 (ponieważ nie ma przerwy;), który aktualizuje się z 2 do 3. Wszystko jest w opisie.
Edward Bagby,
4

Zrobiłem następujące podejście, zostało to rozwiązane dla mnie

jeśli wersja DB: 6

Ex : There is a table with 5 columns

Po uaktualnieniu do: 7 (dodaję 1 nową kolumnę w 3 tabelach)

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

Gdzie: „DATABASE_ALTER_ADD_PAPER_PAID” to zapytanie.

EX: public static final String DATABASE_ALTER_ADD_PAPER_PAID = "ALTER TABLE "
                + TableConstants.MY_PAPERS_TABLE + " ADD COLUMN " + COLUMN_PAPER_PAID + " TEXT;";

Po powyższych dwóch operacjach będzie działać dobrze dla nowego użytkownika instalacji i użytkownika aktualizacji aplikacji

sssvrock
źródło
3

@ Aamirkhan.i myślę, że rozwiązałbyś problem, o którym wspomniałeś w komentarzach dawno temu. Myślę, że nie zwiększyłeś wersji bazy danych. w przeciwnym razie odpowiedzi tutaj są proste. Piszę to, ponieważ może to pomóc każdemu, kto nie zwiększył ani nie zmienił numeru wersji swojej bazy danych, gdy zmieniają tabelę.

dora
źródło
tak, zmiana nazwy bazy danych i odinstalowanie aplikacji i ponowna instalacja rozwiązałaby problem
Aamirkhan
@Aamirkhan, przenieś czek do następnej odpowiedzi, aby bardziej przejrzyste rozwiązanie było dostępne dla publiczności.
AlleyOOP
3

Myślę, że nie powinniśmy tak sprawdzać stanu

 if (newVersion > oldVersion) {
 }

bo jeśli z tego skorzystamy, oznacza to, że za każdym razem, gdy zwiększamy wersję bazy danych, to onUpdrade () wywoła i warunek będzie prawdziwy, więc powinniśmy tak sprawdzić

if(oldVersion==1) 
{

}

więc w tym przypadku, jeśli stara wersja to 2, to warunek będzie fałszywy i użytkownik ze starszą wersją 2 nie zaktualizuje bazy danych (której użytkownik chce tylko dla wersji 1), ponieważ dla tych użytkowników baza danych była już zaktualizowana.

Himanshu arora
źródło
1

Aby dodać nową kolumnę do tabeli, musisz użyć ALTER. W systemie Android możesz dodać nową kolumnę w pliku onUpgrade().

Możesz się zastanawiać, jak onUpgrade()dodasz nową kolumnę?

Podczas implementowania podklasy programu SQLiteOpenHelper, musisz wywołać konstruktor nadklasy: super(context, DB_NAME, null, 1);w konstruktorze klasy. Tam przekazałem 1wersję.

Kiedy zmieniłem wersję 1na powyższą ( 2lub nowszą ), onUpgrade()zostanie wywołany. I wykonaj modyfikacje SQL, które zamierzam zrobić. Konstruktor mojej klasy po zmianie wersji:

public DatabaseHelper(Context context) {
    super(context, DB_NAME, null, 2);//version changed from 1 to 2
}

Sprawdza modyfikacje SQL w ten sposób, konstruktor nadklasy porównuje wersję przechowywanego pliku bazy SQLite z wersją, do której przekazałem super(). Jeśli te (poprzednie i obecne) numery wersji są różne, onUpgrade()zostanie wywołany.

Kod powinien wyglądać następująco:

@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");
    }
}
Blasanka
źródło
1

Po prostu zmień swój kod

prywatna ostateczna int DATABASE_VERSION = 1;

do

prywatne statyczne końcowe int DATABASE_VERSION = 2;

Shahzad Ahmad
źródło
0

Podczas wyszukiwania tego samego problemu natrafiłem na link. Wyjaśnia, jak używać aktualizacji. https://thebhwgroup.com/blog/how-android-sqlite-onupgrade

wyjaśnia, dlaczego używać poniższego kodu

 @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);
        }
    }
Anand
źródło
0

Najłatwiejszym sposobem utworzenia nowej kolumny w tabeli jest dodanie kodu SQL do metody onUpgrade () w klasie SQLiteOpenHelper. Lubić:

@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");
    }
}
Digvij Borda
źródło
0

najpierw zwiększ numer wersji bazy danych. a następnie w onUpgrademetodzie możesz sprawdzić, czy kolumna już istnieje, jeśli nie, to tylko dodaj kolumnę

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

ta metoda jest wyodrębniona z tego łącza Sprawdzanie, czy kolumna istnieje w bazie danych aplikacji w systemie Android

początkujący
źródło