我使用OID作为具有自动增量的主键,但我想使Txn No也具有自动增量。有什么办法可以使其自动递增?我尝试使用循环,但似乎不起作用。

java - 如何在Sqlite中使两列自动递增-LMLPHP

一次单击“保存”时,下一次应为Txn否“ 2”,但我想不起来,因为我使用OID进行自动递增,所以Txn否不能使用它。

这是我的代码:

public class DatabaseHelper extends SQLiteOpenHelper {
    public static final String DATABASE_NAME = "Person.db";
    public static final String TABLE_NAME = "Person_Table";
    public static final String COL_1 = "OID";
    public static final String COL_2 = "TxnNo";
    public static final String COL_3 = "Name";
    public static final String COL_4 = "Amount";
    public static final String COL_5 = "Date";
    public static final String COL_6 = "Description";
    public static final String COL_7 = "Description2";

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table " + TABLE_NAME + " (OID INTEGER PRIMARY KEY AUTOINCREMENT," +
                "TxnNo TEXT, Name TEXT, Amount INTEGER,Date TEXT, Description TEXT,Description2 TEXT)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }

    public boolean insertData(String TxnNo, String Name, String Amount, String Date, String Description, String Description2) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COL_2, TxnNo);
        contentValues.put(COL_3, Name);
        contentValues.put(COL_4, Amount);
        contentValues.put(COL_5, Date);
        contentValues.put(COL_6, Description);
        contentValues.put(COL_7, Description2);
        long result = db.insert(TABLE_NAME, null, contentValues);
        if (result == -1)
            return false;
        else
            return true;
    }

}

最佳答案

使用SQLite AUTOINCREMENT的第一件事实际上并没有增加ID,使用INTEGER PRIMARY KEY会产生几乎相同的结果,除了添加了9223372036854775807行之外。所有AUTOINCREMENT所做的就是强制增加数量(因此,当到达最大的rowid时,会发生SQLITE FULL异常),否则(没有AUTOINCREMENT)可以分配免费的较低数字,从而有可能规避SQLITE FULL异常。

实际上,INTEGER PRIMARY KEY(带有或不带有AUTOINCREMENT)的作用是使rowid的columnn别名(通常隐藏的列,具有唯一的64位带符号整数)。

规则之一是每个表只能对INTEGER PRIMARY KEY(或PRIMARY KEY)进行编码。这是您面临的问题。



一个办法

一种方法是使用插入新行时触发的TRIGGER,并使用该触发器以OID后缀的值更新插入的行。例如

CREATE TRIGGER IF NOT EXISTS increment_tax_number
    AFTER INSERT ON Person_Table
    BEGIN
        UPDATE Person_Table SET TxnNo = 'Txn no '||new.OID WHERE OID =  new.OID;
    END;
INSERT INTO Person_Table VALUES(null,'not a valid tax number as yet','Fred',15000,'2018-01-01','blah','more blah');
INSERT INTO Person_Table VALUES(null,'not a valid tax number as yet','Bert',25000,'2018-03-04','blah','more blah');
SELECT * FROM Person_Table;


对于一个新表,以上结果为:

java - 如何在Sqlite中使两列自动递增-LMLPHP

该解决方案可以通过以下方式合并:

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("create table " + TABLE_NAME + " (OID INTEGER PRIMARY KEY AUTOINCREMENT," +
            "TxnNo TEXT, Name TEXT, Amount INTEGER,Date TEXT, Description TEXT,Description2 TEXT)");
    db.execsql("CREATE TRIGGER If NOT EXISTS increment_tax_number     AFTER INSERT ON Person_Table
BEGIN
    UPDATE Person_Table SET TxnNo = 'Txn no '||new.OID WHERE OID =  new.OID;
END");
}



您需要删除应用程序的数据,卸载应用程序或增加版本号(即使用super(context, DATABASE_NAME, null, 2))。注意您将丢失任何现有数据。不丢失数据将更加复杂。


更有效的解决方案

当然,还有一种选择是仅使用OID,因为您似乎希望将数字部分附加到Txn No,因此甚至不需要浪费一列。需要时可以生成Txn No 1,Txn No 2等。

例如以下将纯粹从OID列生成Txn No:

SELECT Name, 'Txn No '||OID AS txn_no,Amount,Description,Description2 FROM Person_Table;


导致 :-

java - 如何在Sqlite中使两列自动递增-LMLPHP

要合并此解决方案,除了使用适当的查询外,您无需执行其他任何操作(尽管您可能希望删除TxnNo列)

有关AUTOINCREMENT的更多信息

使用AUTOINCREMENT会产生很少需要的开销。 SQLite文档包括:-



  AUTOINCREMENT关键字强加了额外的CPU,内存,磁盘空间和
  磁盘I / O开销,如果没有严格要求,则应避免。它是
  通常不需要。

SQLite Autoincrement


开销是因为使用AUTOINCREMENT时,用于确定新rowid的算法增加了第二阶段,即从sqlite_sequence表中获取相应行,然后使用此表中的较高者和表中的最高rowid(不使用AUTOINCREMENT只是最高的rowid使用表格中的)。因此,必须为每个插入维护和访问此附加表的开销。

因此,使用以下任一方法来定义表会更有效:

CREATE TABLE IF NOT EXISTS Person_Table (OID INTEGER PRIMARY KEY,TxnNo TEXT, Name TEXT, Amount INTEGER,Date TEXT, Description TEXT,Description2 TEXT);



如果您决定使用TxnNo列


要么 :-

CREATE TABLE IF NOT EXISTS Person_Table (OID INTEGER PRIMARY KEY, Name TEXT, Amount INTEGER,Date TEXT, Description TEXT,Description2 TEXT);



如果使用派生的Txn No(更有效的解决方案)

关于java - 如何在Sqlite中使两列自动递增,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51997243/

10-08 23:40