SQLite将字段设置为与插入时生成的id相同的值

时间:2018-01-19 08:50:12

标签: android sqlite android-sqlite

我们要求表中的某些字段需要与其ID具有相同的值。不幸的是,我们当前必须插入新记录,然后,如果需要,运行另一个更新以将重复字段(ID_2)值设置为等于ID。

这是Android Sqlite代码:

mDb.beginTransaction();  

// ... setting various fields here ...
ContentValues contentValues = new ContentValues();
contentValues.put(NAME, obj.getName()); 

// now insert the record
long objId = mDb.insert(TABLE_NAME, null, contentValues);
obj.setId(objId);

// id2 needs to be the same as id:
obj.setId2(objId);

// but we need to persist it so we update it in a SECOND call
StringBuilder query = new StringBuilder();
query.append("update " + TABLE_NAME);
query.append(" set " + ID_2 + "=" + objId);
query.append(" where " + ID + "=" + objId);
mDb.execSQL(query.toString());
mDb.setTransactionSuccessful();

如您所见,我们正在进行第二次调用,将ID_2设置为相同的ID值。有没有办法在INSERT时设置它并避免第二次调用DB?

更新

ID定义如下:

ID + " INTEGER PRIMARY KEY  NOT NULL ," +

3 个答案:

答案 0 :(得分:1)

用于自动增量列的算法是documented,因此您可以在代码中手动实现它,然后使用INSERT的新值。

答案 1 :(得分:1)

这是一个非常难看的黑客,但它可能是:

with id_table as (
    select coalesce(max(seq), 0) + 1 as id_column 
    from sqlite_sequence 
    where name = 'MY_TABLE'
)
insert into MY_TABLE(ID_1, ID_2, SOME, OTHER, COLUMNS)
select id_column, id_column, 'SOME', 'OTHER', 'VALUES'
from id_table

仅当表ID为AUTOINCREMENT时才有效,因此通过记录的sqlite_sequence表进行管理。

我也不知道在并发执行的情况下会发生什么。

答案 2 :(得分:0)

您可以使用后插入触发器,例如

创建表格(至少在本例中),以便 ID_2 定义为INTEGER DEFAULT -1(0或任何负值都可以)

e.g。 CREATE TABLE IF NOT EXISTS triggertest (_id INTEGER PRIMARY KEY ,name TEXT ,id_2 INTEGER DEFAULT -1);

然后你可以使用类似的东西(也许在创建表之后直接创建它,也许在它被使用之前创建它并在完成它之后删除它): -

CREATE TRIGGER triggertesting001 
    AFTER INSERT ON triggertest 
        BEGIN 
            UPDATE triggertest SET id_2 = `_id` 
            WHERE id_2 = -1; 
        END;

使用DROP TRIGGER IF EXISTS triggertesting001;

删除

示例用法(测试): -

INSERT INTO triggertest (name) VALUES('Fred');
INSERT INTO triggertest (name) VALUES('Bert');
INSERT INTO triggertest (name) VALUES('Harry');

结果1: -

enter image description here

结果2(触发掉落的插入再次运行): -

enter image description here

结果3(创建触发器)与上述相同。

结果4(第3次运行插入)赶上,即6行使用_id更新了id_2。

enter image description here

我强烈建议您阅读SQL As Understood By SQLite - CREATE TRIGGER

替代解决方案

另一种方法可以是简单地使用: -

在开始交易之前,请从下面的表格中检索mynextid

ContentValues contentValues = new ContentValues();
contentValues.put(ID,mynextid);
contentvalues.put(ID_2,mynextid++);
contentValues.put(NAME, obj.getName()); 

然后在事务结束时将mynextid的值更新/存储在一个简单的单列,单行表中。

即。你正在管理id(与SQLite在指定'AUTOINCREMENT'时管理id的方式不太相似