Android SQLiteデータベースに新しい列を追加するにはどうすればよいですか?


83

AndroidSQLiteデータベースに1つの問題があります。

1つのfield.StudentFnameを含む1つのテーブルがあり、そのアプリケーションは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は列の定義によって異なります。


1
こんにちは!私はこれを試しましたが、upgrateメソッドで使用し、その中にalter tableクエリも配置しましたが、それでもデータベースに新しい列を追加することはできません。しかし、新しい列を追加して名前を変更するクエリを作成すると、データベースとテーブル名の両方で新しい列を追加できますが、alter tableメソッドを使用すると、そうすることができません。データベースとテーブルの名前を変更することは目的のタスクではありません。alterで動作するはずです。 ..私は、ALTER TABLEの方法でそれを行うことができないのですtable..still
アーミル・カーン

@NagarjunaReddy返信が遅くなってすみません。このメソッドを使用できますdb.execSQL( "UPDATE table SET key = key + 1 WHERE name =?"、new String [] {name});
DevYudh 2013

3
データベースのバージョンを増やすことを忘れないでください。そうしないと、onUpgrade()が呼び出されません。以下のコードのバージョン番号を増やします。これは、SQLiteOpenHelperクラスを拡張するクラスのコンストラクターに存在します。super(コンテキストコンテキスト、文字列名、CursorFactoryファクトリ、int newVersion)
appdroid 2014年

アプリがフリーズし、ログ猫に次のようなメッセージがたくさんあります:データベース '+ data + user + 0 + com ..._ db'の接続プールは、フラグ0x5のスレッド1(メイン)への接続を許可できませんでした。なぜこれが起こったのですか?
マハディ2018

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

ユーザーが複数のバージョンをアップグレードするときにコードが機能すること、およびupdateステートメントが必要なアップグレードを1つだけ実行することを確認する必要があります。これについてもう少し詳しくは、このブログをチェックしてください


デフォルトの文字列値で変更された列を作成する場合はどうすればよいですか?
shridutt kothari 2015年

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

これを試しましたが、upgrateメソッドでaltertableメソッドを使用して新しい列を追加できません。
アーミルカーン2011

こんにちは!私はこれを試しましたが、upgrateメソッドで使用し、その中にalter tableクエリも配置しましたが、それでもデータベースに新しい列を追加することはできません。しかし、新しい列を追加して名前を変更するクエリを作成すると、データベースとテーブル名の両方で新しい列を追加できますが、alter tableメソッドを使用すると、そうすることができません。データベースとテーブルの名前を変更することは目的のタスクではありません。alterで動作するはずです。 table ..それでも、alter tableメソッドでは実行できません
Aamirkhan 2011

@ user370305アプリを初めてインストールする新しいユーザーのために、tablle createステートメントに新しい列を追加する必要がありますか?
Ahesanali Suthar 2016

15

おそらく、if / thenの代わりにswitchを使用する、もう少し洗練されたアプローチで、任意のスキーマから最新のスキーマにアップグレードします...

テーブルを変更するための構文に関する適切なページもあります: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

    }

}

これは、複数のアップグレードを処理する方法です。どのバージョンからのものかを確認してください!
リカルド

バージョン1から3に直接移行した場合(誰かがアプリを自動更新しない場合)、ケース2に到達しません。
TyMarc18年

@ TyMarc--はい、バージョン2、次に3にアップグレードされます。スイッチは古いバージョンを使用します。したがって、この例では、古いバージョンは1です。コードはケース1を実行し、バージョン1から2にアップグレードし、次にケース2を実行します(中断がないため)。これは2から3にアップグレードします。説明にはそれで大丈夫です。
エドワードバグビー

4

私は次のアプローチをしました、それは私のために解決されます

DBバージョンの場合:6

Ex : There is a table with 5 columns

にアップグレードすると:7(3つのテーブルに1つの新しい列を追加します)

 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;";

上記の2つの操作の後、フレッシュインストールユーザーとアプリアップグレードユーザーは正常に機能します


3

@ Aamirkhan.iは、ずっと前にコメントで言及した問題を解決したと思います。データベースのバージョンを増やしていなかったと思います。そうでなければ、ここでの答えは簡単です。テーブルを変更するときにデータベースのバージョン番号を増やしたり変更したりしていない人に役立つ可能性があるため、これを書いています。


はい、データベース名を変更し、アプリケーションをアンストールして再インストールすると、問題が解決します
Aamirkhan 2013年

@Aamirkhan、チェックを次の回答に移動して、より明確な解決策が一般に公開されるようにしてください。
AlleyOOP 2014年

3

そんな状態をチェックしてはいけないと思います

 if (newVersion > oldVersion) {
 }

これを使用すると、データベースのバージョンを増やすたびにonUpdrade()が呼び出され、条件がtrueになるため、次のように確認する必要があります。

if(oldVersion==1) 
{

}

したがって、この場合、古いバージョンが2の場合、条件はfalseになり、古いバージョン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

コードを変更するだけです

private final int DATABASE_VERSION = 1;

private static final 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

テーブルに新しい列を作成する最も簡単な方法は、SQLiteOpenHelperクラスのonUpgrade()メソッドにSQLを追加することです。お気に入り:

@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のアプリケーションデータベースに列が存在するかどうかを確認します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.