Obtenir l'identifiant généré après l'insertion


138

J'utilise SQLite avec Android et je souhaite connaître le meilleur moyen d'obtenir l'identifiant généré de la ligne que j'ai insérée.

Une solution, je pense, fait une recherche après include, mais elle ne semble pas la meilleure façon.

Réponses:


271

La insertméthode renvoie la idligne qui vient d'être insérée ou -1s'il y a eu une erreur lors de l'insertion.

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

où db est SQLiteDatabase.


21
J'ai lu sur les spécifications. "Renvoie: l'ID de ligne de la ligne nouvellement insérée, ou -1 si une erreur s'est produite" le rowId est le même que mon champ généré "ID clé primaire auto-incrément"?
Marcos Vasconcelos

29
Oui, c'est pareil.
GrAnd

3
@GrAnd, mais que se passe-t-il si je supprime certaines lignes "début-milieu" de ma table, alors je casse la séquence des n-ièmes lignes avec l'id généré = n. L'ID de ligne renvoyé restera-t-il le même que l'ID d'auto-incrémentation généré?
UnknownJoe

1
Que faire si vous devez faire INSERT OU UPDATE et obtenir l'identifiant?
Timo

1
@UnknownJoe Je sais que c'est un ancien message. Mais peut être utile pour quelqu'un. L'identifiant de ligne et l'identifiant auto-incrémenté seront identiques même s'ils sont supprimés du milieu.
Raj kannan Iyyappan

8

Si vous utilisez 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) ;

Si l'exécution de la requête utilise 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);

Si vous utilisez la chambre

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

5

J'ai vérifié les sources. insertméthode utilise une sqlite3_last_insert_rowidfonction pour renvoyer un identifiant. D'après la documentation: https://www.sqlite.org/c3ref/last_insert_rowid.html L'ID de ligne est la colonne cachée ou une colonne de type INTEGER PRIMARY KEYsi elle est déclarée.

Chaque entrée dans la plupart des tables SQLite (à l'exception des WITHOUT ROWIDtables) a une clé entière signée 64 bits unique appelée " rowid ". Le rowid est toujours disponible en tant que colonne non déclarée nommée ROWID, OID ou _ROWID_ tant que ces noms ne sont pas également utilisés par les colonnes explicitement déclarées. Si la table a une colonne de type, cette colonne est un autre alias pour le rowid .INTEGER PRIMARY KEY

C'est donc la _IDcolonne par défaut généralement


1

J'ai eu pas mal de problèmes avec cela sur mySQL, le LAST_INSERT_ID n'est pas un moyen fiable d'obtenir l'ID, si vous avez des utilisateurs qui martèlent la base de données, l'ID renvoyé peut ne pas être l'ID qui a été inséré par la requête que vous avez exécutée, plusieurs d'autres utilisateurs peuvent avoir un impact sur le retour de cet identifiant. Nous avions un serveur avec une moyenne de 7000 utilisateurs par minute et il trébuchait toujours.

La solution que nous avions était d'utiliser les données de la requête que vous avez insérée, puis de rechercher ce résultat à l'aide de ces données. Vous faites quand même une demande à la recherche du dernier identifiant. Donc, vous pouvez aussi bien faire une table SELECT id FROM où field = var et field = var pour obtenir l'id. C'est un léger impact sur les performances de la requête, mais un résultat beaucoup plus fiable est renvoyé.


3
Cela nécessite que vos valeurs de colonne pour chaque ligne soient uniques (ou pour la plupart uniques) ou risquent de renvoyer plusieurs identifiants.
Richard Barker

0

On peut simplement obtenir la dernière ligne insérée _id en utilisant last_insert_rowid(). Un exemple de code est comme ci-dessous.

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

}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.