Android SQLite Veritabanına yeni Sütun nasıl eklenir?


83

Android SQLiteveritabanıyla ilgili bir sorunum var .

Bir field.StudentFname içeren bir tablom var ve bu uygulama Android 2.3.1 ile iyi çalışıyor ve şimdi başka bir alan eklersem uygulamam düzgün çalışmıyor.

Veritabanını çok iyi bilen biri bana yardım edebilir mi?

Yanıtlar:


189

yönteminizde ALTER TABLEişlevi şu şekilde kullanabilirsiniz 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");
  }
}

Açıkça, SQLite sütun tanımına bağlı olarak farklılık gösterecektir.


1
Selam! bunu denedim yükseltme yönteminde kullandım ve bunun içine de tablo sorgusunu değiştirdim. ama yine de veritabanına yeni sütun ekleyemiyorum ... ama ya yeni sütun eklemek ve yeniden adlandırmak için bir sorgu yazdığımda hem veritabanı hem de tablo adı yeni sütun ekleyebiliyorum..ama tablo değiştirme yönteminin yardımıyla bunu yapamıyorum ... veritabanını ve tabloyu yeniden adlandırmak istenen görev değil ... alter ile çalışıyor olmalı tablo.. yine de tablo değiştirme yöntemiyle
yapamıyorum

@NagarjunaReddy geç cevap için özür dilerim. bu yöntemi kullanabilirsiniz db.execSQL ("UPDATE table SET key = key + 1 WHERE name =?", new String [] {name});
DevYudh

3
Veritabanı sürümünü artırmayı unutmayın, aksi takdirde onUpgrade () çağrılmayacaktır. SQLiteOpenHelper sınıfını genişleten sınıfın yapıcısında bulunacak aşağıdaki koddaki sürüm numarasını artırın. super (Bağlam bağlamı, Dize adı, CursorFactory fabrikası, int newVersion)
appdroid

Uygulama donuyor ve kedide buna benzer birçok mesaj var: '+ data + user + 0 + com ..._ db' veritabanı için bağlantı havuzu, 0x5 bayrakları ile 1 numaralı iş parçacığına (ana) bağlantı sağlayamadı. Bu neden oldu?
Mahdi

if (newVersion > oldVersion) burada koşul gereksizdir çünkü onUpgradekendisi yalnızca bu koşul karşılandığında çağrılır, yani yeni sürüm eski sürümden daha büyüktür
başlangıç

31

Kendi uygulamamda yardıma ihtiyaç duyduğumda bu konuya rastladım, ancak yanıtların çoğunda sorunlar gördüm. Aşağıdakileri yapmanızı tavsiye ederim:

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

Kullanıcılar 1'den fazla sürümü yükselttiklerinde kodun çalışacağından ve güncelleme bildiriminin yalnızca gereken yükseltmeyi çalıştırdığından emin olmak istersiniz. Bununla ilgili biraz daha fazla bilgi için bu bloga göz atın .


varsayılan String değerine sahip değiştirilmiş bir sütun oluşturmak istiyorsak ne yapmalıyız?
shridutt kothari

22

Bunu yapmanın en kolay yolu, bazı eklemektir SQL to the onUpgrade()Gözlerinde farklı bir yöntem SQLiteOpenHelper class. Gibi bir şey:

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

Bunu denedim ama yine de yükseltme yönteminde tablo değiştirme yöntemini kullanarak yeni sütun ekleyemiyorum.
Aamirkhan

Selam! bunu denedim yükseltme yönteminde kullandım ve bunun içine de tablo sorgusunu değiştirdim. ama yine de veritabanına yeni sütun ekleyemiyorum ... ama ya yeni sütun eklemek ve yeniden adlandırmak için bir sorgu yazdığımda hem veritabanı hem de tablo adı yeni sütun ekleyebiliyorum..ama tablo değiştirme yönteminin yardımıyla bunu yapamıyorum ... veritabanını ve tabloyu yeniden adlandırmak istenen görev değil ... alter ile çalışıyor olmalı tablo.. yine de tabloyu değiştir yöntemiyle
yapamıyorum

@ user370305, uygulamayı ilk kez yükleyen yeni kullanıcılar için tablo oluştur ifadesine yeni sütun eklemem gerekir mi?
Ahesanali Suthar

15

Belki de eğer / o zaman yerine switch kullanarak herhangi bir şemadan en yeni şemaya yükseltilecek biraz daha zarif bir yaklaşım ...

Burada ayrıca bir tabloyu değiştirmek için sözdiziminde iyi bir sayfa var: 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

    }

}

Bu, birden çok yükseltmeyi gerçekleştirmenin yoludur. Hangi sürümün geldiği kontrol ediliyor!
Ricardo

Doğrudan sürüm 1'den 3'e geçerseniz (birisi uygulamayı otomatik olarak güncellemezse), durum 2'ye ulaşamazsınız.
TyMarc

@ TyMarc - Evet, sürüm 2'ye ve ardından 3'e yükseltilecek. Anahtar eski sürümü kullanıyor. Dolayısıyla, örneğinizde eski sürüm 1'dir. Kod, daha sonra sürüm 1'den 2'ye yükseltilen durum 1'i çalıştırır ve ardından 2'den 3'e yükseltilen durum 2'yi (kesinti olmadığı için) çalıştırır. Hepsi tanımda orada.
Edward Bagby

4

Aşağıdaki yaklaşımı yaptım, benim için yeniden yerleştirildi

DB sürümü ise: 6

Ex : There is a table with 5 columns

7'ye yükselttiğinizde (3 tabloya 1 yeni sütun ekliyorum)

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

Nerede: "DATABASE_ALTER_ADD_PAPER_PAID" sorgudur.

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

Yukarıdaki iki işlemden sonra, yeni yükleme kullanıcısı ve uygulama yükseltme kullanıcısı için sorunsuz çalışır.


3

@ Aamirkhan.i uzun zaman önce yorumlarda bahsettiğiniz sorunu çözeceğinizi düşünüyorum. Veri tabanı versiyonunu arttırmadığınızı düşünüyorum. ya da buradaki cevaplar basittir. bunu yazıyorum çünkü bir tabloyu değiştirirken veri tabanı sürüm numarasını artırmayan veya değiştirmeyen herkese yardımcı olabilir.


evet, veritabanı adını değiştirmek ve uygulamayı
kaldırmak

@Aamirkhan, lütfen çeki bir sonraki cevaba taşıyın, böylece daha net çözüm halka açık olsun.
AlleyOOP

3

Bence durumu böyle kontrol etmemeliyiz

 if (newVersion > oldVersion) {
 }

çünkü eğer bunu kullanırsak, veritabanı sürümünü her artırdığımızda onUpdrade () çağıracak ve koşul doğru olacaktır, bu yüzden böyle kontrol etmeliyiz

if(oldVersion==1) 
{

}

bu durumda eski sürüm 2 ise koşul yanlış olacaktır ve eski sürüm 2'ye sahip kullanıcı veritabanını güncellemeyecektir (bu kullanıcı yalnızca sürüm 1 için), çünkü bu kullanıcılar için veritabanı zaten güncellenmiştir.


1

Tabloya yeni bir sütun eklemek için kullanmanız gerekir ALTER. Android'de yeni sütunu onUpgrade().

Merak ediyor olabilirsiniz onUpgrade(), yeni sütunu nasıl ekleyeceksiniz?

Bir alt sınıfını uygularken SQLiteOpenHelper, sınıf yapıcınızda süper sınıf yapıcı: çağırmanız gerekir super(context, DB_NAME, null, 1);. Orada 1sürüm için geçtim .

Sürümü 1yukarı ( 2veya daha büyük) olarak değiştirdiğimde onUpgrade()çağrılacak. Ve yapmak istediğim SQL değişikliklerini gerçekleştirin. Sürüm değiştirildikten sonra sınıf kurucum:

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

SQL değişiklikleri bu şekilde kontrol eder, süper sınıf yapıcısı depolanan SQLite db dosyasının sürümünü geçtiğim sürümle karşılaştırır super(). Bu (önceki ve şimdi) sürüm numaraları farklıysa onUpgrade()çağrılır.

Kod şu şekilde görünmelidir:

@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

Sadece kodunuzu değiştirin

özel nihai int DATABASE_VERSION = 1;

-e

private static final int DATABASE_VERSION = 2;


0

Aynı sorunu ararken bağlantıyla karşılaştım. Yükseltmenin nasıl kullanılacağını açıklar. https://thebhwgroup.com/blog/how-android-sqlite-onupgrade

aşağıdaki kodun neden kullanılacağını açıklıyor

 @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

Bir tabloda yeni bir sütun oluşturmanın en kolay yolu, SQLiteOpenHelper sınıfındaki onUpgrade () yöntemine biraz SQL eklemektir. Sevmek:

@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

ilk olarak, veritabanı sürüm numarasını artırın. ve daha sonra onUpgradeyöntemde, sütunun zaten mevcut olup olmadığını kontrol edebilirsiniz, daha sonra yalnızca sütunu ekleyin

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

bu yöntem bu bağlantıdan çıkarılır Android'de bir uygulama veritabanında bir sütun olup olmadığını kontrol etme

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.