Ich habe eine Tabelle Nachrichten mit Spalten-ID (Primärschlüssel, automatische Inkrementierung) und Inhalt (Text).
Ich habe eine Tabelle Benutzer mit Spalten Benutzername (Primärschlüssel, Text) und Hash.
Eine Nachricht wird von einem Absender (Benutzer) an viele Empfänger (Benutzer) gesendet, und ein Empfänger (Benutzer) kann viele Nachrichten haben.
Ich habe eine Tabelle Messages_Recipients mit zwei Spalten erstellt: MessageID (bezogen auf die ID-Spalte der Messages-Tabelle und Recipient (bezogen auf die Spalte Benutzername in der Users-Tabelle). Diese Tabelle repräsentiert die Viele-zu-Viele-Beziehung zwischen Empfängern und Nachrichten.
Die Frage, die ich habe, ist folgende. Die ID einer neuen Nachricht wird erstellt, nachdem sie in der Datenbank gespeichert wurde. Aber wie kann ich einen Verweis auf die MessageRow halten, die ich gerade hinzugefügt habe, um diese neue MessageID abzurufen?
Ich kann natürlich immer in der Datenbank nach der zuletzt hinzugefügten Zeile suchen, aber das könnte möglicherweise eine andere Zeile in einer Multithread-Umgebung zurückgeben?
EDIT: Wie ich es für SQLite verstehe, können Sie die verwenden SELECT last_insert_rowid()
. Aber wie rufe ich diese Anweisung von ADO.Net auf?
Mein Persistenzcode (Nachrichten und Nachrichtenempfänger sind DataTables):
public void Persist(Message message)
{
pm_databaseDataSet.MessagesRow messagerow;
messagerow=messages.AddMessagesRow(message.Sender,
message.TimeSent.ToFileTime(),
message.Content,
message.TimeCreated.ToFileTime());
UpdateMessages();
var x = messagerow;//I hoped the messagerow would hold a
//reference to the new row in the Messages table, but it does not.
foreach (var recipient in message.Recipients)
{
var row = messagesRecipients.NewMessages_RecipientsRow();
row.Recipient = recipient;
//row.MessageID= How do I find this??
messagesRecipients.AddMessages_RecipientsRow(row);
UpdateMessagesRecipients();//method not shown
}
}
private void UpdateMessages()
{
messagesAdapter.Update(messages);
messagesAdapter.Fill(messages);
}
quelle
Antworten:
Mit SQL Server würden Sie SCOPE_IDENTITY () AUSWÄHLEN, um den letzten Identitätswert für den aktuellen Prozess abzurufen.
Mit SQlite sieht es nach einer automatischen Erhöhung aus, die Sie durchführen würden
SELECT last_insert_rowid()
sofort nach dem Einsatz.
http://www.mail-archive.com/[email protected]/msg09429.html
Als Antwort auf Ihren Kommentar, um diesen Wert zu erhalten, möchten Sie SQL- oder OleDb-Code wie folgt verwenden:
using (SqlConnection conn = new SqlConnection(connString)) { string sql = "SELECT last_insert_rowid()"; SqlCommand cmd = new SqlCommand(sql, conn); conn.Open(); int lastID = (Int32) cmd.ExecuteScalar(); }
quelle
If the table has a column of type INTEGER PRIMARY KEY then that column is another alias for the rowid.
Eine andere Möglichkeit besteht darin, sich die Systemtabelle anzusehen
sqlite_sequence
. Ihre SQLite-Datenbank verfügt automatisch über diese Tabelle, wenn Sie eine Tabelle mit dem Primärschlüssel für die automatische Inkrementierung erstellt haben. In dieser Tabelle verfolgt sqlite das Feld für die automatische Inkrementierung, sodass der Primärschlüssel auch nach dem Löschen einiger Zeilen oder nach einem fehlgeschlagenen Einfügen nicht wiederholt wird (mehr dazu hier http://www.sqlite.org/autoinc) .html ).Diese Tabelle bietet also den zusätzlichen Vorteil, dass Sie den Primärschlüssel Ihres neu eingefügten Elements auch dann herausfinden können, wenn Sie etwas anderes eingefügt haben (natürlich in anderen Tabellen!). Nachdem Sie sichergestellt haben, dass Ihre Einfügung erfolgreich ist (andernfalls erhalten Sie eine falsche Nummer), müssen Sie einfach Folgendes tun:
select seq from sqlite_sequence where name="table_name"
quelle
Ich hatte Probleme mit der Verwendung
SELECT last_insert_rowid()
in einer Multithread-Umgebung. Wenn ein anderer Thread in eine andere Tabelle mit Autoinc eingefügt wird, gibt last_insert_rowid den Autoinc-Wert aus der neuen Tabelle zurück.Hier heißt es im Dokument:
Das ist von sqlite.org doco
quelle
Beispielcode aus der @ polyglot-Lösung
SQLiteCommand sql_cmd; sql_cmd.CommandText = "select seq from sqlite_sequence where name='myTable'; "; int newId = Convert.ToInt32( sql_cmd.ExecuteScalar( ) );
quelle
Laut Android Sqlite Get Last Insert Row ID gibt es eine andere Abfrage:
SELECT rowid from your_table_name order by ROWID DESC limit 1
quelle
ORDER BY
. Sollte schneller sein, aber ich habe das nicht getestet:SELECT MAX(rowid) FROM your_table_name