Uzyskaj wygenerowany identyfikator po wstawieniu


138

Używam SQLite z Androidem i chcę poznać najlepszy sposób uzyskania wygenerowanego identyfikatora wstawionego wiersza.

Myślę, że rozwiązanie polega na wyszukiwaniu po uwzględnieniu, ale nie wygląda to najlepiej.

Odpowiedzi:


271

W insertmetoda zwraca idz rzędu zaledwie włożona lub -1czy nie wystąpił błąd podczas wprowadzania.

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

gdzie jest db SQLiteDatabase.


21
Czytałem o specyfikacjach. „Zwraca: identyfikator wiersza nowo wstawionego wiersza lub -1, jeśli wystąpił błąd” wartość rowId jest taka sama, jak w wygenerowanym polu „id autoincrement klucza podstawowego”?
Marcos Vasconcelos

29
Tak, to jest to samo.
GrAnd

3
@GrAnd, ale co, jeśli usunę kilka wierszy „początkowo-środkowych” z mojej tabeli, więc zrywam sekwencję n-tych wierszy z wygenerowanym id = n. Czy ten zwrócony identyfikator wiersza pozostanie taki sam jak wygenerowany identyfikator autoincrement?
UnknownJoe

1
Co jeśli musisz WSTAWIĆ LUB AKTUALIZOWAĆ i uzyskać identyfikator?
Timo

1
@UnknownJoe Wiem, że to stary post. Ale może być pomocny dla kogoś. Identyfikator wiersza i automatycznie zwiększany identyfikator będą takie same, nawet jeśli zostaną usunięte ze środka.
Raj kannan Iyyappan

8

Jeśli używasz 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) ;

W przypadku wykonywania zapytania użyj 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);

Jeśli używasz 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);
}

5

Sprawdziłem źródła. insertmetoda użyj sqlite3_last_insert_rowidfunkcji, aby zwrócić identyfikator. Zgodnie z dokumentacją: https://www.sqlite.org/c3ref/last_insert_rowid.html Identyfikator wiersza to ukryta kolumna lub kolumna typu, INTEGER PRIMARY KEYjeśli jest zadeklarowana.

Każdy wpis w większości tabel SQLite (z wyjątkiem WITHOUT ROWIDtabel) ma unikalny 64-bitowy klucz z liczbą całkowitą ze znakiem, zwany „ rowid ”. Rowid jest zawsze dostępny jako niezadeklarowana kolumna o nazwie ROWID, OID lub _ROWID_, o ile te nazwy nie są również używane przez jawnie zadeklarowane kolumny. Jeśli tabela ma kolumnę typu,INTEGER PRIMARY KEY to ta kolumna jest innym aliasem dla identyfikatora wiersza .

Więc to jest _IDzwykle kolumna domyślna


1

Miałem z tym sporo problemów na mySQL, LAST_INSERT_ID nie jest niezawodnym sposobem na uzyskanie identyfikatora, jeśli masz użytkowników łamiących bazę danych, zwracany identyfikator może nie być identyfikatorem wstawionym przez zapytanie, które wykonałeś, kilka inni użytkownicy mogą mieć wpływ na zwrot tego identyfikatora. Mieliśmy serwer ze średnio 7000 użytkownikami na minutę i zawsze się potykał.

Rozwiązaniem, które mieliśmy, było użycie danych z wstawionego zapytania, a następnie wyszukanie tego wyniku przy użyciu tych danych. I tak wykonujesz żądanie szukające ostatniego identyfikatora. Więc równie dobrze możesz zrobić tabelę SELECT id FROM, gdzie field = var i field = var, aby uzyskać identyfikator. Jest to niewielki spadek wydajności zapytania, ale zwrócono znacznie bardziej wiarygodny wynik.


3
Wymaga to, aby wartości kolumn dla każdego wiersza były unikalne (lub w większości unikalne) lub ryzykowały zwrócenie wielu identyfikatorów.
Richard Barker

0

Można po prostu pobrać ostatni wstawiony wiersz _id za pomocą last_insert_rowid(). Przykładowy kod jest jak poniżej.

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

}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.