插入后获取生成的ID

145

我正在使用SQLite和Android,想知道获取插入行生成的id的最佳方法。

我认为一种解决方法是在include之后进行搜索,但这并不是最佳方式。

5个回答

279

insert 方法返回刚插入的行的 id,如果在插入期间发生错误,则返回 -1

long id = db.insert(...);

db是SQLiteDatabase对象。


25
在规格说明中我读到了这样的内容:"返回:新插入行的行ID,如果发生错误则返回-1"。那么这个行ID是否与我生成的字段"id primary key autoincrement"相同呢? - Marcos Vasconcelos
4
@GrAnd,但是如果我在表格中删除了一些“起始-中间”行,这样就会打破具有生成的id = n的第n行的序列。 那么返回的行ID是否仍将保持与生成的自增ID相同? - UnknownJoe
1
如果您需要执行INSERT OR UPDATE并获取ID,该怎么办? - Timo
@Log.d 你应该使用insertOrThrow以便收集更多关于错误发生的信息。(我知道现在有点晚了,但这也可能会帮助其他读者) - mr5
1
@UnknownJoe 我知道这是旧帖子。但可能对某些人有帮助。即使从中间删除,行ID和自增ID仍将相同。 - Raj kannan Iyyappan
显示剩余2条评论

12

如果使用 ContentValues:

 DBHelper db =new DBHelper();// your dbHelper
 ContentValues values = new ContentValues();
  values.put("firstName","Ahmad");
 values.put("lastName","Aghazadeh");
 long insertedId= db.getSQLiteDatabase().insert("user", "", values) ;

如果执行查询,请使用select last_insert_rowid()

String sql = "INSERT INTO [user](firstName,lastName) VALUES (\"Ahmad\",\"Aghazadeh\"); select last_insert_rowid()";
 DBHelper itemType =new DBHelper();// your dbHelper
 c = db.rawQuery(sql, null);
 if (c.moveToFirst())
    result = c.getLong(0);

如果使用 Room

@Entity
class User {
    @PrimaryKey(autoGenerate = true)
    public int id;
    //...
}


@Dao
public interface UserDao{
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    long insert(User user);

    // Insert multiple users
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    long[] insert(User... user);
}

8
我已经检查了来源。insert方法使用sqlite3_last_insert_rowid函数返回一个id。根据文档:https://www.sqlite.org/c3ref/last_insert_rowid.html,如果声明了主键,行id就是隐藏列或类型为INTEGER PRIMARY KEY的列。
大多数SQLite表(除了WITHOUT ROWID表)中的每个条目都有一个名为“rowid”的唯一64位带符号整数键。只要这些名称未被显式声明的列使用,rowid始终作为未声明列名为ROWID、OID或_ROWID_的可用列。如果表具有类型为INTEGER PRIMARY KEY的列,则该列是rowid的另一个别名。
所以这通常是默认的_ID列。

1

可以使用 last_insert_rowid() 来获取最后插入的行的 _id。示例代码如下。

/**
 * Return Last inserted row id(auto incremented row) (_id)
 * @return
 */
public int getLastAddedRowId() {
    String queryLastRowInserted = "select last_insert_rowid()";

    final Cursor cursor = database.rawQuery(queryLastRowInserted, null);
    int _idLastInsertedRow = 0;
    if (cursor != null) {
        try {
            if (cursor.moveToFirst()) {
                _idLastInsertedRow = cursor.getInt(0);
            }
        } finally {
            cursor.close();
        }
    }

    return _idLastInsertedRow;

}

Rupesh,请查看这个问题。https://stackoverflow.com/questions/65140180/sqlite-generated-id-after-insert-raw-query - AppDeveloper

1
我在mySQL上遇到了一些问题,LAST_INSERT_ID不是获取ID的可靠方法。如果有多个用户同时访问数据库,返回的ID可能不是你运行的查询插入的ID,其他用户可能会影响此ID的返回。我们的服务器平均每分钟处理7000个用户,但它总是出现故障。
我们的解决方案是使用插入的查询数据,然后使用该数据搜索结果。无论如何,您都在请求最后一个ID。所以您可以使用SELECT id FROM table where field=var and field=var来获取ID。查询性能略有下降,但返回的结果更加可靠。

3
每行的列值需要是唯一的(或者大多数情况下唯一),否则会返回多个ID。 - Richard Barker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接