【问题标题】:delete a column in sqlite android在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 android-sqlite


【解决方案1】:

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

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

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

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

所以:-

  1. 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 方法不会失败
  1. 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
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2019-11-07
  • 2011-12-24
相关资源
最近更新 更多