Получить сгенерированный идентификатор после вставки


140

Я использую SQLite с Android и хочу знать, как лучше всего получить сгенерированный идентификатор вставленной мной строки.

Я думаю, что решение требует поиска после включения, но это выглядит не лучшим образом.

Ответы:


274

В insertметоде возвращает idиз строки просто вставляются или , -1если произошла ошибка во время вставки.

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

где дб SQLiteDatabase.


22
Читал по спецификациям. «Возвращает: идентификатор новой вставленной строки или -1, если произошла ошибка», rowId совпадает с моим сгенерированным полем «автоинкремент первичного ключа id»?
Маркос Васконселос

30
Да, это то же самое.
GrAnd

4
@GrAnd, а что, если я удалю несколько строк "start-middle" в своей таблице, так что я сломаю последовательность n-ых строк сгенерированным id = n. Останется ли возвращенный идентификатор строки таким же, как сгенерированный идентификатор автоинкремента?
UnknownJoe

1
Что делать, если вам нужно сделать ВСТАВИТЬ ИЛИ ОБНОВЛЕНИЕ и получить идентификатор?
Timo

1
@UnknownJoe Я знаю, что это старый пост. Но может быть кому-то полезно. Идентификатор строки и автоматически увеличиваемый идентификатор будут такими же, даже если они будут удалены из середины.
Радж Каннан Ийяппан

9

Если использовать 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) ;

Если запрос exec использовать 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);
}

6

Я проверил источники. insertметод использовать sqlite3_last_insert_rowidфункцию для возврата идентификатора. Согласно документации: https://www.sqlite.org/c3ref/last_insert_rowid.html Идентификатор строки - это скрытый столбец или столбец типа, INTEGER PRIMARY KEYесли он объявлен.

Каждая запись в большинстве таблиц SQLite (кроме WITHOUT ROWIDтаблиц) имеет уникальный 64-битный целочисленный ключ со знаком, называемый " rowid ". Идентификатор строки всегда доступен как необъявленный столбец с именем ROWID, OID или _ROWID_, если эти имена также не используются явно объявленными столбцами. Если в таблице есть столбец типа,INTEGER PRIMARY KEY то этот столбец является еще одним псевдонимом для rowid .

_IDОбычно это столбец по умолчанию


1

У меня было довольно много проблем с этим на mySQL, LAST_INSERT_ID не является надежным способом получить идентификатор, если у вас есть пользователи, забивающие базу данных, возвращенный идентификатор может не быть идентификатором, который был вставлен в запрос, который вы выполнили, несколько другие пользователи могут повлиять на возврат этого идентификатора. У нас был сервер со средней скоростью 7000 пользователей в минуту, и он всегда останавливался.

Решение, которое у нас было, заключалось в том, чтобы использовать данные из введенного вами запроса, а затем искать этот результат, используя эти данные. Вы все равно делаете запрос на поиск последнего идентификатора. Таким образом, вы можете также сделать SELECT id FROM table, где field = var и field = var, чтобы получить идентификатор. Это небольшое снижение производительности по запросу, но результат был гораздо более надежным.


3
Это требует, чтобы значения столбца для каждой строки были уникальными (или в основном уникальными), в противном случае существует риск возврата нескольких идентификаторов.
Ричард Баркер

0

Можно просто получить последнюю вставленную строку _id, используя last_insert_rowid(). Пример кода приведен ниже.

/**
 * 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;

}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.