【发布时间】:2012-01-07 15:59:00
【问题描述】:
我在使用 Android SQLite 数据库时遇到了一个问题。
我有一张表,其中包含一个字段。StudentFname 并且该应用程序在 Android 2.3.1 上运行良好,现在如果我添加另一个字段,那么我的应用程序无法正常运行。
谁能帮帮我,非常了解数据库,
【问题讨论】:
我在使用 Android SQLite 数据库时遇到了一个问题。
我有一张表,其中包含一个字段。StudentFname 并且该应用程序在 Android 2.3.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 会根据列定义而有所不同。
【讨论】:
if (newVersion > oldVersion) 条件在这里是不必要的,因为onUpgrade 本身仅在满足此条件时才被调用,即新版本大于旧版本
我在自己的应用程序上需要帮助时遇到了这个帖子,但看到很多答案都有问题。我建议您执行以下操作:
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。
【讨论】:
最简单的方法是在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");
}
}
【讨论】:
也许使用 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
}
}
【讨论】:
我已经做了以下方法,这是为我解决的
如果数据库版本: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;";
经过以上两个操作,全新安装用户和应用升级用户都可以正常使用
【讨论】:
@Aamirkhan.我认为您早就解决了您在 cmets 中提到的问题。我认为您没有增加数据库版本。否则这里的答案是直截了当的。我写这篇文章是因为它可能会帮助那些在更改表时没有增加或更改数据库版本号的人。
【讨论】:
我认为我们不应该那样检查条件
if (newVersion > oldVersion) {
}
因为如果我们使用这个,这意味着每次我们增加数据库版本时都会调用 onUpdrade() 并且条件为 true ,所以我们应该这样检查
if(oldVersion==1)
{
}
所以在这种情况下,如果旧版本为 2,则条件将为 false,使用旧版本 2 的用户将不会更新数据库(用户只需要版本 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 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");
}
}
【讨论】:
只需更改您的代码
私有最终 int DATABASE_VERSION = 1;
到
private static final int DATABASE_VERSION =2;
【讨论】:
我在搜索相同问题时遇到了链接。它解释了如何使用升级。 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);
}
}
【讨论】:
在表上创建新列的最简单方法是在 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");
}
}
【讨论】:
首先,增加数据库版本号。然后在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
【讨论】:
注意到没有答案寻找存在的列:
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");
}
【讨论】: