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

时间:2018-08-24 03:55:29

标签: java android sqlite

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

Here is the picture

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

这是我的代码:

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;
    }

}

3 个答案:

答案 0 :(得分:2)

使用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 ,当插入新行时触发该 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;

对于新表,以上结果为:-

enter image description here

可以通过使用以下解决方案来合并:-

@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; 

产生:-

enter image description here

要集成此解决方案,除了使用适当的查询外,您无需执行其他任何操作(尽管您可能希望删除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(更有效的解决方案)

答案 1 :(得分:1)

表中不能有2个AUTOINCREMENT变量。但是,现在您大方了:TxnNo TEXT这很奇怪。 您可以寻找这些变体sql-auto-increment-several

答案 2 :(得分:1)

可能是Sqlite没有为两列提供自动增量。 所以我有几种方法

  • 首先,您需要使用“ TxnNo”作为INTEGER或LONG。
  • 在插入新记录时,
  • 获得最大“ TxnNo”并将其增加1。仅当整个数据库在本地同步时才有可能。如果未完全同步,则可能会发生重复。
  • 使用“ TxnNo”作为LONG并设置当前时间(以毫秒为单位)。每次都会给您唯一的号码。无需获得最高我更喜欢这种方式。因为我也在用这种方式。