如何将新列添加到 Android SQLite 数据库?

Posted

技术标签:

【中文标题】如何将新列添加到 Android SQLite 数据库?【英文标题】:How to add new Column to Android SQLite Database? 【发布时间】:2012-01-07 15:59:00 【问题描述】:

我在使用 android SQLite 数据库时遇到了一个问题。

我有一张表,其中包含一个字段。StudentFname 并且该应用程序在 Android 2.3.1 上运行良好,现在如果我添加另一个字段,那么我的应用程序无法正常运行。

谁能帮帮我,非常了解数据库,

【问题讨论】:

【参考方案1】:

您可以在 onUpgrade() 方法上使用 ALTER TABLE 函数,如下所示:

@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 会根据列定义而有所不同。

【讨论】:

嗨!我已经尝试过这个我在升级方法中使用过的方法,并且在其中我也放置了更改表查询。但我仍然无法将新列添加到数据库中。但是当我编写查询以添加新列并重命名时数据库和表名都比我能够添加新列..但是在alter table方法的帮助下我无法这样做..重命名数据库和表不是所需的任务..它应该与alter一起使用表..我仍然无法使用更改表方法来做到这一点.. @NagarjunaReddy 抱歉回复晚了。你可以使用这个方法 db.execSQL("UPDATE table SET key = key + 1 WHERE name=?", new String[] name); 不要忘记增加数据库版本,否则不会调用onUpgrade()。在下面的代码中增加版本号,它将出现在扩展 SQLiteOpenHelper 类的类的构造函数中。 super(Context context, String name, CursorFactory factory, int newVersion) 应用程序冻结,我在日志 cat 上有很多这样的消息:数据库 '+data+user+0+com..._db' 的连接池无法授予与线程 1 的连接(主)带有标志 0x5 的。为什么会这样? if (newVersion > oldVersion) 条件在这里是不必要的,因为onUpgrade 本身仅在满足此条件时才被调用,即新版本大于旧版本【参考方案2】:

我在自己的应用程序上需要帮助时遇到了这个帖子,但看到很多答案都有问题。我建议您执行以下操作:

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 个版本时代码可以正常工作,并且更新语句只运行它需要的一次升级。如需更多信息,请查看blog。

【讨论】:

如果我们想用默认的字符串值创建改变的列怎么办??【参考方案3】:

最简单的方法是在SQLiteOpenHelper class 中添加一些SQL to the onUpgrade() 方法。比如:

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

【讨论】:

我已经尝试过了,但我仍然无法在升级方法中使用 alter table 方法添加新列。 嗨!我已经尝试过这个我在升级方法中使用过的方法,并且在其中我也放置了更改表查询。但我仍然无法将新列添加到数据库中。但是当我编写查询以添加新列并重命名时数据库和表名都比我能够添加新列..但是在alter table方法的帮助下我无法这样做..重命名数据库和表不是所需的任务..它应该与alter一起使用表..我仍然无法使用更改表方法来做到这一点 @user370305 我是否必须在 tablle create 语句中为首次安装应用程序的新用户添加新列?【参考方案4】:

也许使用 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

    


【讨论】:

这是处理多次升级的方法。检查来自哪个版本! 如果您直接从版本 1 转到版本 3(如果有人不自动更新应用程序),您将无法达到案例 2。 @TyMarc-- 是的,它将升级到版本 2 然后 3。交换机使用旧版本。因此,在您的示例中,旧版本是 1。然后代码将运行案例 1,从版本 1 升级到 2,然后运行案例 2(因为没有中断;),从 2 升级到 3。描述中都可以。【参考方案5】:

我已经做了以下方法,这是为我解决的

如果数据库版本: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;";

经过以上两个操作,全新安装用户和应用升级用户都可以正常使用

【讨论】:

【参考方案6】:

@Aamirkhan.我认为您早就解决了您在 cmets 中提到的问题。我认为您没有增加数据库版本。否则这里的答案是直截了当的。我写这篇文章是因为它可能会帮助那些在更改表时没有增加或更改数据库版本号的人。

【讨论】:

是的,更改数据库名称并卸载应用程序并重新安装它可以解决问题 @Aamirkhan,请将支票移至下一个答案,以便向公众提供更清晰的解决方案。【参考方案7】:

我认为我们不应该那样检查条件

 if (newVersion > oldVersion) 
 

因为如果我们使用这个,这意味着每次我们增加数据库版本时都会调用 onUpdrade() 并且条件为 true ,所以我们应该这样检查

if(oldVersion==1) 



所以在这种情况下,如果旧版本为 2,则条件将为 false,使用旧版本 2 的用户将不会更新数据库(用户只需要版本 1),因为对于这些用户,数据库已经更新。

【讨论】:

【参考方案8】:

要向表中添加新列,您需要使用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 db 文件的版本与我传递给 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");
    

【讨论】:

【参考方案9】:

只需更改您的代码

私有最终 int DATABASE_VERSION = 1;

private static final int DATABASE_VERSION =2;

【讨论】:

【参考方案10】:

我在搜索相同问题时遇到了链接。它解释了如何使用升级。 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);
        
    

【讨论】:

【参考方案11】:

在表上创建新列的最简单方法是在 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");
    

【讨论】:

【参考方案12】:

首先,增加数据库版本号。然后在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();
    

此方法提取自此链接Checking if a column exists in an application database in Android

【讨论】:

【参考方案13】:

注意到没有答案寻找存在的列:

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

【讨论】:

以上是关于如何将新列添加到 Android SQLite 数据库?的主要内容,如果未能解决你的问题,请参考以下文章

如何将新列添加到现有表 symfony - orocommerce

如何将新列动态添加到 bigquery 中已存在的表..?

如何使用 apache commons 将新列添加到 csv 文件

如何将新列添加到按 groupby 分组的分层数据框中

如何将新列和相应的行特定值添加到火花数据帧?

如何使用apache commons将新列添加到csv文件中