在sqlite android中删除一列

Posted

技术标签:

【中文标题】在sqlite android中删除一列【英文标题】:delete a column in sqlite android 【发布时间】:2021-12-29 10:33:52 【问题描述】:

我想删除 sqlite 表中的一列。我正在使用 DROP COLUMN,但它给出了错误ADD or RENAME expected, got 'DROP'。如何删除此表中的列?

    private static final String DATABASE_NAME = "Manager.db";
    public static final String TABLE_NAME = "MANAGER_TABLE";
    public static final String _ID = "_id";
    public static final String  STATUS = "status";

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

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

    

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
        if (oldVersion < 2) 
            db.execSQL("ALTER TABLE " + TABLE_NAME + " DROP COLUMN " + STATUS);
        

【问题讨论】:

SQLite 从 3.35.0 版本开始支持 DROP COLUMN,android 尚不支持。 这能回答你的问题吗? How to delete or add column in SQLITE? 【参考方案1】:

您不仅需要删除onUpgrade 方法中的列,还应该从onCreate 方法中的SQL 中删除列;否则,新安装将具有现有的 STATUS 列。

这将简化删除列,因为您可以从 onUpgrade 方法调用 onCreate 来创建与新安装完全相同的表。

请注意,如果您有任何其他表,那么您应该更改创建 SQL 以包含 IF NOT EXISTS(请参阅下面的示例)

尝试创建没有IF NOT EXISTS 的现有表将导致失败。

所以:-

    onCreate方法改为

:-

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


不需要添加 IF NOT EXISTS,但如果在任何其他表(如果有)上使用,则调用 onCreate 方法不会失败
    onUpgrade 步骤更改为

:-

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    if (oldVersion < 2) 
        String suffix = "_old";
        db.execSQL("ALTER TABLE " + TABLE_NAME + " RENAME TO " + TABLE_NAME + suffix + ";");
        onCreate(db);
        /* Preserves existing data */
        db.execSQL("INSERT INTO " + TABLE_NAME + " SELECT ID," + _ID + " FROM " + TABLE_NAME + suffix + ";");
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME + suffix + ";");
    

工作示例

以下是使用 DBHelper 的工作示例。

MainActivity 根据它所在的数据库版本添加一行:-

public class MainActivity extends AppCompatActivity 

    DBHelper dbHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /* Testing */
        dbHelper = new DBHelper(this);
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int version = db.getVersion();

        ContentValues cv = new ContentValues();
        cv.put(DBHelper._ID,"somedata");
        if (version == 1) 
            cv.put(DBHelper.STATUS,version);
        
        db.insert(DBHelper.TABLE_NAME,null,cv);
    

运行 1 第一次运行时使用版本 1,状态列保持如下:-

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 ,"
            + STATUS + " TEXT NOT NULL, "
            + _ID + " TEXT NOT NULL)";
    db.execSQL(create_table);

使用应用检查(数据库检查器)显示:-

所以数据库有 1 行。

运行 2

对于第二次运行,状态列被注释掉,版本更改为 2 并运行导致:-

即现有数据已保留(禁止状态)。该表没有状态列。已添加另一行。

运行 3

没有代码更改,但应用程序被卸载以反映版本 2 的新安装,结果只是添加到新版本 2 表中的 1 行:-

【讨论】:

感谢您的回答,它成功了。只是在旁注中,如果存在多列并且您只需要删除一列怎么办。假设我们有NAMEVALUE_ID,我们想保留这些。你会怎么写这行db.execSQL("INSERT INTO " + TABLE_NAME + " SELECT ID," + _ID + " FROM " + TABLE_NAME + suffix + ";"); @mumer 要提取的列以逗号分隔的列表形式跟随在 SELECT 后面,注意顺序应该是它们出现的顺序(按照 CREATE SQL 的顺序),除非指定了列和顺序在一对括号内。在链接中,请参阅流程图中的列。关于 SELECT INSERT,请阅读 INSERT INTO table SELECT 部分。链接是sqlite.org/lang_insert.html

以上是关于在sqlite android中删除一列的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中删除 SQLite 中的行

在 Android 中删除 ListiView 和 SQLite 行

在Android SQLITE中删除多行

调试符号时读取 SQLite-net.dll 失败

如何以编程方式从 Android 中删除 SQLite 数据库

如何在android中启动活动时从sqlite数据库中删除所有行(数据)