【问题标题】:Android Studio Sqllite autoincrement resetAndroid Studio Sqlite 自动增量重置
【发布时间】:2021-06-17 05:43:33
【问题描述】:
db.execSQL("CREATE TABLE " +DBTable0+ "("+ROW2+" INTEGER PRIMARY KEY AUTOINCREMENT, "+ROW3+" VARCHAR NOT NULL, "+ROW0+" TEXT NOT NULL, "+ROW1+" VARCHAR NOT NULL)");

这是我的数据库的创建表命令。

我想重置 ROW2 的值。

例如,我在这张表上有 5 条记录。

1, save1, 这是一个 Save1, 11.25

2, save2, This is a Save2, 23.48

3, save3, This is a Save3, 09.45

4,save4,这是一个 Save4,11.55

5, save5, This is a Save5, 21.00

我想删除 save2。当我删除它或其他删除时,我想重置 ROW2 索引,所以

1, save1, 这是一个 Save1, 11.25

2, save3, This is a Save3, 09.45

3, save4, 这是一个 Save4, 11.55

4, save5, This is a Save5, 21.00

像这样……

我该怎么做?

【问题讨论】:

  • 永远不要乱用自动增量值!
  • 为什么要更改 ID?您要解决的实际问题是什么?
  • 此记录显示在 ListView 中。
  • 我将通过 ListViews 选择记录。然后我可以删除和更新我选择的项目的记录。所以当我删除中间的任何记录时。 id 正在混合和删除虚假记录

标签: java android sqlite


【解决方案1】:

AUTOINCREMENT 关键字的全部意义在于永远不要重复使用 rowid。它存储为表分配的最高值,并且当插入没有在插入语句中明确给出的 rowid 的新行时,选择一个高于存储的数字的数字。如果没有AUTOINCREMENT,它只会选择一个高于表中当前最大 rowid 的数字(如果最大值是最大可能的有符号 64 位整数,它会随机选择一些较小的数字,希望在放弃之前丢失一个)。

如果你想回收rowid数字,你要么必须手动找到丢失的数字并在UPDATE语句中显式使用它们,或者没有INTEGER PRIMARY KEY列,并在删除行后运行VACUUM。如果没有 INTEGER PRIMARY KEY 列别名 rowid,sqlite 将在这种情况下重新排列它们。或者您可以将表的行(减去INTEGER PRIMARY KEY 列)复制到新表中以获取新的rowid。所有这些都是非常低效的方法,并且不可取。忍受已删除行的间隙。

必读以了解 rowid、INTEGER PRIMARY KEY 列和 AUTOINCREMENT

https://www.sqlite.org/rowidtable.html

https://www.sqlite.org/lang_createtable.html#rowid

https://www.sqlite.org/autoinc.html

我将通过 ListViews 选择记录。然后我可以删除和更新我选择的项目的记录。所以当我删除中间的任何记录时。 id 正在混合和删除虚假记录

听起来您假设某个列表的位置与行的 rowid 相同?难怪你有问题。明确跟踪 rowid 并在删除请求的数据时使用它。 XY problem的经典案例。

【讨论】:

  • db.execSQL("ALTER TABLE " +ACT.DBTable0+ " DROP " +ACT.ROW2); db.execSQL("ALTER TABLE " +ACT.DBTable0+ " ADD " +ACT.ROW2+ " PRIMARY KEY AUTOINCREMENT");
  • @CrossV4 嗯...不。您不能从表中删除列。
  • 附录:从 Sqlite 3.35.0 ALTER TABLE 开始支持删除列,但如果它是主键或其他情况则不支持。
【解决方案2】:

要重置分配的 rowid 以在使用 AUTOINCREMENT 时补偿已删除的行,您必须进行两项更改:-

  1. 您必须更改(更新)乱序的每一行的 rowidrowid 的别名以遵循新的序列和
  2. 那么您必须将系统表 sqlite_sequence 中的相应行更改(更新)为分配的最高 rowid

这完全不可取,并且会大大加剧使用 AUTOINCREMENT 的低效率(当您很有可能不需要使用 AUTOINCREMENT 时)。

  • SQLite Autoincrement 包括
  • AUTOINCREMENT 关键字会带来额外的 CPU、内存、磁盘空间和磁盘 I/O 开销,如果不是严格需要,应该避免使用。通常不需要。

事实上,永远不要依赖 rowid 不是 SQlite 指定的任何东西

  • <column_name> INTEGER PRIMARY KEY(带或不带 AUTOINCREMENT)使 成为 rowid 的别名)。

###你说:-

我想重置 ROW2 的值。

我建议重新评估您的需求,仅在确实有需要时才想要这个,而这很可能是没有的。

###你接着说

我将通过 ListViews 选择记录。然后我可以删除和更新我选择的项目的记录。所以当我删除中间的任何记录时。 id 正在混合和删除虚假记录

如果您使用 CursorAdapter,例如SimpleCursorAdapter,onItemClick和onItemLongClick的第4个参数是id

请注意,要使用 CursorAdapter,名称为 _id 的列必须存在于作为 ListView 源的 Cursor 中,并且该列应包含 rowid。您可以使用 BaseColumns._ID,它是一个具有值 _id 的常量。

通常您会将表中的列定义为_id INTEGER PRIMARY KEY

您也可以使用rowid AS _id, *,在这种情况下,_id 列将附加到所有其他列。

可以在here找到其他适配器的这个和其他选项/说明

##工作示例

但是,如果您坚持,那么下面的示例可以满足您的要求。

注意此示例对 2 个表执行相同的操作(有效)。

  • 第一个表 table1 使用 AUTOINCREMENT
  • 第二个表 table2 没有 AUTOINCREMENT 编码,但结果相同(除了 sqlite_sequence 没有修改,因为不需要,因为 sqlite_sequence 中没有行,因为 AUTOINCREMENT 也没有被编码)。

主要代码在Database Helper(SQLiteOpenHelper的子类)即DBHelper.java中:-

public class DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;

    public static final String TBL_TABLE1 = "table1";
    public static final String TBL_TABLE2 = "table2";
    public static final String COL_TABLE_COL1 = "col1";
    public static final String COL_TABLE_COL2 = "col2";
    public static final String COL_TABLE_COL3 = "col3";

    private static final String crt_table1_sql = "CREATE TABLE IF NOT EXISTS " + TBL_TABLE1 + "(" +
            COL_TABLE_COL1 + " INTEGER PRIMARY KEY AUTOINCREMENT," +
            COL_TABLE_COL2 + " TEXT NOT NULL," +
            COL_TABLE_COL3 + " TEXT NOT NULL" +
            ")";
    private static final String crt_table2_sql = "CREATE TABLE IF NOT EXISTS " + TBL_TABLE2 + "(" +
            COL_TABLE_COL1 + " INTEGER PRIMARY KEY," +
            COL_TABLE_COL2 + " TEXT NOT NULL," +
            COL_TABLE_COL3 + " TEXT NOT NULL" +
            ")";

    SQLiteDatabase mDB;

    public DBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onConfigure(SQLiteDatabase db) {
        super.onConfigure(db);
        db.disableWriteAheadLogging();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(crt_table1_sql);
        db.execSQL(crt_table2_sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }

    public void insert(String col2, String col3) {
        ContentValues cv = new ContentValues();
        cv.put(COL_TABLE_COL2,col2);
        cv.put(COL_TABLE_COL3,col3);
        mDB.beginTransaction();
        mDB.insert(TBL_TABLE1,null,cv);
        mDB.insert(TBL_TABLE2,null,cv);
        mDB.setTransactionSuccessful();
        mDB.endTransaction();
    }

    public void deleteByValues(String col2, String col3) {
        String whereclause = COL_TABLE_COL2 + "=? AND " + COL_TABLE_COL3 + "=?";
        String[] args = new String[]{col2,col3};
        mDB.beginTransaction();
        mDB.delete(TBL_TABLE1,whereclause,args);
        mDB.delete(TBL_TABLE2,whereclause,args);
        rationaliseCol1Values();
        mDB.setTransactionSuccessful();
        mDB.endTransaction();
    }

    private void rationaliseCol1Values() {
        ContentValues cv = new ContentValues();
        Cursor csr = mDB.query(TBL_TABLE1,null,null,null,null,null,COL_TABLE_COL1 + " ASC");

        int rowcount = csr.getCount();
        long expected_id = 1;
        long current_id;
        String where_clause = COL_TABLE_COL1 + "=?";
        String[] args = new String[1];

        while (csr.moveToNext()) {
            current_id = csr.getLong(csr.getColumnIndex(COL_TABLE_COL1));
            if (current_id != expected_id) {
                cv.clear();
                cv.put(COL_TABLE_COL1,expected_id);
                args[0] = String.valueOf(current_id);
                mDB.update(TBL_TABLE1,cv,where_clause,args);
                mDB.update(TBL_TABLE2,cv,where_clause,args);
            }
            expected_id++;
        }
        csr.close();
        // Now adjust sqlite_sequence
        where_clause = "name=?";
        args[0] = TBL_TABLE1;
        cv.clear();
        cv.put("seq",String.valueOf(rowcount));
        mDB.update("sqlite_sequence",cv,where_clause,args);
    }

    public void logTableRows(int stage) {

        String tablenamne_column = "tablename";    
        Cursor[] csr = new Cursor[] {
                mDB.query(TBL_TABLE1,new String[]{"'table1' AS " + tablenamne_column + ",*"},null,null,null,null,null),
                mDB.query(TBL_TABLE2,new String[]{"'table2' AS " + tablenamne_column + ",*"}, null,null,null,null,null)
        };
        MergeCursor csr3 = new MergeCursor(csr);
        StringBuilder sb = new StringBuilder("Data in both tables consists of " + String.valueOf(csr3.getCount()) + " rows :-");

        while (csr3.moveToNext()) {
            sb.append(
                    "\n\tTableName = " + csr3.getString(csr3.getColumnIndex(tablenamne_column)
                    )
            ).append(" " + COL_TABLE_COL1 + " value is " + csr3.getString(csr3.getColumnIndex(COL_TABLE_COL1))
            ).append(" " + COL_TABLE_COL2 + " value is " + csr3.getString(csr3.getColumnIndex(COL_TABLE_COL2))
            ).append(" " + COL_TABLE_COL3 + " value is" + csr3.getString(csr3.getColumnIndex(COL_TABLE_COL3))
            );
        }
        Log.d("DATA4STAGE" + String.valueOf(stage),sb.toString());
    }
}
  • rowid(因此别名为 COL1)的核心操作由 rationaliseCol1Values() 方法进行。这本身作为 deleteByValues 方法的一部分被调用。
    • 如果有根据 id 又名 COL1 删除的方法,那么这也会调用 rationaliseCol1Values() 方法)。李>
  • logTableRows 只是为了将表输出到日志中而存在。

用于测试上述内容的调用活动是:-

public class MainActivity extends AppCompatActivity {

    DBHelper mDBHlpr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBHlpr = new DBHelper(this);
        manipulateSomeData();
    }

    private void manipulateSomeData() {
        mDBHlpr.logTableRows(0);
        mDBHlpr.insert("TEST001","TESTING001");
        mDBHlpr.insert("TEST002","TESTING001");
        mDBHlpr.insert("TEST003","TESTING001");
        mDBHlpr.insert("TEST004","TESTING001");
        mDBHlpr.insert("TEST005","TESTING001");
        mDBHlpr.insert("TEST006","TESTING001");
        mDBHlpr.insert("TEST007","TESTING001");
        mDBHlpr.insert("TEST008","TESTING001");
        mDBHlpr.insert("TEST009","TESTING001");
        mDBHlpr.logTableRows(1);

        mDBHlpr.deleteByValues("TEST005","TESTING001");
        mDBHlpr.logTableRows(2);
        mDBHlpr.deleteByValues("TEST008","TESTING001");
        mDBHlpr.logTableRows(3);
        mDBHlpr.deleteByValues("TEST003","TESTIN001");
        mDBHlpr.logTableRows(4);
    }
}
  • 这个:-
    1. 列出行(首次运行时不列出)。
    2. 添加 9 行,其中 COL2 是唯一的(再次仅在首次运行时)。
    3. 列出所有 9 行(第一次运行)。
    4. 删除在 COL2 中具有“TEST005”值的所有行AND在 COL3 中具有“TESTING001”值。
    5. 列出行(注意如何维护 COL1 的序列)。
    6. 删除在 COL2 中具有“TEST008”值的所有行AND在 COL3 中具有“TESTING001”值。
  1. 列出行(注意如何维护 COL1 的序列)。
  2. 删除在 COL2 中具有值“TEST003”的所有行AND在 COL3 中具有“TESTIN001”值。 由于拼写错误(缺少 G)而无法执行
  3. 列出行(注意如何维护 COL1 的序列)。

输出到日志的结果是:-

2018-12-31 12:43:21.618 2269-2269/so53976714.so53976714 D/DATA4STAGE0: Data in both tables consists of 0 rows :-
2018-12-31 12:43:21.657 2269-2269/so53976714.so53976714 D/DATA4STAGE1: Data in both tables consists of 18 rows :-
        TableName = table1 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table1 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table1 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table1 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table1 col1 value is 5 col2 value is TEST005 col3 value isTESTING001
        TableName = table1 col1 value is 6 col2 value is TEST006 col3 value isTESTING001
        TableName = table1 col1 value is 7 col2 value is TEST007 col3 value isTESTING001
        TableName = table1 col1 value is 8 col2 value is TEST008 col3 value isTESTING001
        TableName = table1 col1 value is 9 col2 value is TEST009 col3 value isTESTING001
        TableName = table2 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table2 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table2 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table2 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table2 col1 value is 5 col2 value is TEST005 col3 value isTESTING001
        TableName = table2 col1 value is 6 col2 value is TEST006 col3 value isTESTING001
        TableName = table2 col1 value is 7 col2 value is TEST007 col3 value isTESTING001
        TableName = table2 col1 value is 8 col2 value is TEST008 col3 value isTESTING001
        TableName = table2 col1 value is 9 col2 value is TEST009 col3 value isTESTING001
2018-12-31 12:43:21.666 2269-2269/so53976714.so53976714 D/DATA4STAGE2: Data in both tables consists of 16 rows :-
        TableName = table1 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table1 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table1 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table1 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table1 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table1 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table1 col1 value is 7 col2 value is TEST008 col3 value isTESTING001
        TableName = table1 col1 value is 8 col2 value is TEST009 col3 value isTESTING001
        TableName = table2 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table2 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table2 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table2 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table2 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table2 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table2 col1 value is 7 col2 value is TEST008 col3 value isTESTING001
        TableName = table2 col1 value is 8 col2 value is TEST009 col3 value isTESTING001
2018-12-31 12:43:21.675 2269-2269/so53976714.so53976714 D/DATA4STAGE3: Data in both tables consists of 14 rows :-
        TableName = table1 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table1 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table1 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table1 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table1 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table1 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table1 col1 value is 7 col2 value is TEST009 col3 value isTESTING001
        TableName = table2 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table2 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table2 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table2 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table2 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table2 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table2 col1 value is 7 col2 value is TEST009 col3 value isTESTING001
2018-12-31 12:43:21.681 2269-2269/so53976714.so53976714 D/DATA4STAGE4: Data in both tables consists of 14 rows :-
        TableName = table1 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table1 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table1 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table1 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table1 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table1 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table1 col1 value is 7 col2 value is TEST009 col3 value isTESTING001
        TableName = table2 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table2 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table2 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table2 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table2 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table2 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table2 col1 value is 7 col2 value is TEST009 col3 value isTESTING001

#NOTE 不推荐使用上述方法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    相关资源
    最近更新 更多