如何在sqlite android中进行更改

Posted

技术标签:

【中文标题】如何在sqlite android中进行更改【英文标题】:how to make changes in sqlite android 【发布时间】:2021-11-12 20:27:48 【问题描述】:

我有一个运行良好的现有数据库,我需要在其中添加一些更改。这些更改后数据库无法正常工作。我应该如何更改数据库以保留现有的并添加新的更改?任何帮助表示赞赏。这是原始数据库

public class DBHelper extends SQLiteOpenHelper 
    private static final String DATABASE_NAME = "DATABASE_NAME.db";
    public static final String TABLE_NAME = "POSITION_TABLE";
    private static final String _ID = "_id";
    private static final String RADIO_BUTTON_POSITION = "radio_button_position";


    public DBHelper(@Nullable Context context) 
        super(context, DATABASE_NAME, null, 1);
    

    @Override
    public void onCreate(SQLiteDatabase db) 
        String create_table = "CREATE TABLE " + TABLE_NAME + "( "
                + "ID INTEGER PRIMARY KEY ,"
                + RADIO_BUTTON_POSITION + " TEXT NOT NULL, "
                + _ID + " TEXT NOT NULL)";
        db.execSQL(create_table);

    

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
        db.execSQL("drop Table if exists " + TABLE_NAME);
        onCreate(db);
    


    

      public boolean updateButtonPosition(String _id,String radio_button_position)
        SQLiteDatabase database = this.getWritableDatabase();
        String selection = "_id = ?";
        ContentValues contentValues = new ContentValues();
        contentValues.put(_ID,_id);
        contentValues.put(RADIO_BUTTON_POSITION,radio_button_position);
        long result = database.update(TABLE_NAME , contentValues , _ID + " =? " ,
                new String[]_id);
        if (result == -1)
            return false;
         else 
            return true;
        


    

      public int readButtonPosition(String _id,String radio_button_position)
    
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery("SELECT " + RADIO_BUTTON_POSITION + " FROM "
                +TABLE_NAME+" WHERE " + _ID +" =? " , new String[] String.valueOf(_id));
       
        if(cursor.moveToFirst())
            return cursor.getInt(cursor.getColumnIndex(RADIO_BUTTON_POSITION));
         else 
            return 0;
        
    

这是我要在上面的db中添加的新内容。

private static final String LAST_NO = "LAST_NO";

public boolean updateNumber(String _id,int last_no)
    SQLiteDatabase database = this.getWritableDatabase();
    String selection = "_id = ?";
    ContentValues contentValues = new ContentValues();
    contentValues.put(_ID,_id);
    contentValues.put(LAST_NO,last_no);
    long result = database.update(TABLE_NAME , contentValues , _ID + " =? " ,
            new String[]_id);
    if (result == -1)
        return false;
     else 
        return true;
    



【问题讨论】:

尝试卸载并重新安装应用程序。 我做到了,但仍然没有帮助。 尝试在清单文件的应用标签中添加tools:replace="android:allowBackup"android:allowBackup="false" 【参考方案1】:

您需要更改表以添加新的 LAST_NO 列,因为您要保留现有数据。那就是您要升级数据库,这就是 onUpgrade 方法的用途。

如果版本号增加,则调用 onUpgrade 方法。所以(1)首先要做的就是把版本号从1改成2。

即将super(context, DATABASE_NAME, null, 1); 更改为super(context, DATABASE_NAME, null, 2);

由于任何新安装(而不是升级)都将使用版本 2,因此 onCreate 方法应反映升级,因此 (2) 将其更改为:-

@Override
public void onCreate(SQLiteDatabase db) 
    String create_table = "CREATE TABLE " + TABLE_NAME + "( "
            + "ID INTEGER PRIMARY KEY ,"
            + RADIO_BUTTON_POSITION + " TEXT NOT NULL, "
            + LAST_NO + " INTEGER DEFAULT 0, " //<<<< ADDED FOR version 2
            + _ID + " TEXT NOT NULL)";
    db.execSQL(create_table);

您可能需要也可能不需要 DEFAULT 子句

(3) 然后您需要更改 onUpgrade 方法以 ALTER 表并 删除表 (您将丢失所有数据)NOT 调用 onCreate 方法 (如果未删除表,这将失败(如果您有 CREATE TABLE IF NOT EXISTS ..... 然后它不会失败))

onUpgrade 方法应该检查是否从版本 1 升级到了 2,并且只有在这样的情况下才应该 ALTER 表。因此,您需要检查传递给该方法的 newVersion 是否为 2。如果是,则使用 execSQL 方法发出 ALTER 命令以添加 COLUMN。例如onUpgrade 方法可以是:-

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    /* commmented out for version 2*/
    // db.execSQL("drop Table if exists " + TABLE_NAME);
    // onCreate(db);

    /* Add upgrade for version 2 */
    if (oldVersion == 1 && newVersion == 2) 
        db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN " + LAST_NO + " INTEGER DEFAULT 0");
    

然后表格将被更改以包含新列。

附加 - 渐进式升级:-

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    /* commmented out for version 2*/
    // db.execSQL("drop Table if exists " + TABLE_NAME);
    // onCreate(db);

    /* Add upgrade for version 2 */
    if (oldVersion < 2) 
        db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN " + LAST_NO + " INTEGER DEFAULT 0");
    
    if (oldversion <3) 
       ....
    
    /* an so on */

【讨论】:

非常感谢。如果您想添加一个新列,只需一个问题,onUpgrade 中的条件是否为 (oldVersion == 2 &amp;&amp; newVersion == 3) 以包含所有现有的和新的更改? @user16566034 如果您想涵盖多次升级,那么您需要进行不同的测试并确保升级的顺序正确。所以 1-2 将是第一个遇到 oldversion 我如何将这些测试放入 onUpgrade 的代码中并获得升级序列? @user16566034 只需按顺序排列代码,首先是if (oldversion &lt; 2) .....,然后是if (oldversion &lt; 3) ....,依此类推。所以 if 块是从最低到最高处理的。编辑答案以提供示例。【参考方案2】:

您似乎正在向表中添加一个新列,因此您需要完成升级过程。

要触发升级,您需要增加构造函数中给出的版本

您当前将版本1 作为调用构造函数超类的最后一个参数

public DBHelper(@Nullable Context context) 
        super(context, DATABASE_NAME, null, 1);
    

所以这可能是您的第二个数据库版本,所以这个值应该是2

例如

public DBHelper(@Nullable Context context) 
        super(context, DATABASE_NAME, null, 2);
    

或更笼统地

 super(context, DATABASE_NAME, null, DATABASE_VERSION);

然后将调用onUpgrade 方法,因为存储在数据库中的版本号与您打开它时使用的当前版本号不匹配。

您的onUpgrade 删除现有表并重新创建它,但由于您当前的onCreate 没有添加新列LAST_NO,这也需要更新为类似

@Override
    public void onCreate(SQLiteDatabase db) 
        String create_table = "CREATE TABLE " + TABLE_NAME + "( "
                + "ID INTEGER PRIMARY KEY ,"
                + RADIO_BUTTON_POSITION + " TEXT NOT NULL, "
                + "LAST_NO" + " INTEGER, "
                + _ID + " TEXT NOT NULL)";
        db.execSQL(create_table);

    

如果您想保留数据库中的现有数据,而不是删除数据库并在onUpgrade 中重新创建它,您应该使用ALTER TABLE 命令代替(但onCreate 应该始终是新架构)

【讨论】:

以上是关于如何在sqlite android中进行更改的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android设备中用NDK编译SQLite并且对SQLite进行操作

如何在 SQLite 查询中忽略重音(Android)

如何在android中使用sqlite连接表

如何在android应用程序中嵌入sqlite数据库文件

如何在sqlite中更改月份

Android中如何使用命令行查看内嵌数据库SQLite3