我将OID用作具有自动增量的主键,但是我想使Txn No也具有自动增量。有什么办法可以使其自动递增?我尝试使用循环,但似乎不起作用。
当我单击“保存”一次时,下一次应为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;
}
}
答案 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;
对于新表,以上结果为:-
可以通过使用以下解决方案来合并:-
@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;
产生:-
要集成此解决方案,除了使用适当的查询外,您无需执行其他任何操作(尽管您可能希望删除TxnNo列)
使用AUTOINCREMENT会产生很少需要的开销。 SQLite文档包括:-
AUTOINCREMENT关键字强加了额外的CPU,内存,磁盘空间和 磁盘I / O开销,如果没有严格要求,则应避免。它是 通常不需要。
开销是因为使用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);
或:-
CREATE TABLE IF NOT EXISTS Person_Table (OID INTEGER PRIMARY KEY, Name TEXT, Amount INTEGER,Date TEXT, Description TEXT,Description2 TEXT);
答案 1 :(得分:1)
表中不能有2个AUTOINCREMENT
变量。但是,现在您大方了:TxnNo TEXT
这很奇怪。
您可以寻找这些变体sql-auto-increment-several
答案 2 :(得分:1)
可能是Sqlite没有为两列提供自动增量。 所以我有几种方法