Frage

Ich versuche, wenn zu finden es eine zuverlässige Art und Weise ist ( SQLite verwenden) zu finden die ID der nächsten Zeile eingefügt werden, , bevor es eingefügt wird . Ich brauche die ID für einen anderen Insert-Anweisung zu verwenden, haben aber nicht die Möglichkeit, sofort einsetzen und die nächste Zeile zu bekommen.

Ist die Vorhersage der nächsten ID so einfach, wie die letzte id bekommen und eine Zugabe? Ist das eine Garantie?

Edit: Etwas mehr Argumentation ... Ich kann nicht sofort einsetzen, da der Einsatz durch den Benutzer kann am Ende abgebrochen. Der Benutzer wird einige Änderungen vornehmen, SQL-Anweisungen werden gespeichert und von dort aus kann der Benutzer entweder speichern (Einfügen alle Zeilen auf einmal) oder abzubrechen (nicht etwas zu ändern). Im Fall eines Programmabsturzes ist die gewünschte Funktionalität, dass nichts geändert wird.

War es hilfreich?

Lösung

So oder Verschrottung oder eine Reihe von Datenbank-Operationen auf einmal zu begehen ist genau das, was Transaktionen sind für. Abfrage BEGIN;, bevor der Benutzer beginnt das Hantieren und COMMIT;, sobald er / sie getan hat. Sie garantiert, dass entweder alle Änderungen übernommen werden (wenn Sie begehen) oder alles verschrottet wird (wenn Sie ROLLBACK; abfragen, wenn das Programm abstürzt, Strom ausfällt, etc). Sobald Sie aus dem db lesen, sind Sie auch garantiert, dass die Daten bis zum Ende der Transaktion gut ist, so können Sie greifen MAX(id) oder was auch immer Sie wollen, ohne sich Gedanken über Rennbedingungen.

http://www.sqlite.org/lang_transaction.html

Andere Tipps

Versuchen SELECT * FROM SQLITE_SEQUENCE WHERE name='TABLE';. Dies wird ein Feld namens seq enthalten, die die größte Zahl für die ausgewählte Tabelle ist. 1 zu diesem Wert die nächste ID zu erhalten.

Siehe auch die SQLite Autoincrement Artikel , die, wo die oben genannten Informationen ist herkam.

Cheers!

Sie kann wahrscheinlich mit dem Hinzufügen von 1 zu dem Wert weg zurück von sqlite3_last_insert_rowid unter bestimmten Bedingungen zum Beispiel unter Verwendung der gleichen Datenbankverbindung und es gibt keine andere gleichzeitige Schriftsteller. Natürlich können Sie auf der SQLite-Quellcode beziehen sich auf diese Annahmen zu sichern.

Allerdings könnten Sie auch ernsthaft in Erwägung ziehen, einen anderen Ansatz verwenden, erfordert nicht die nächste ID vorherzusagen. Auch wenn Sie es richtig, für die Version von SQLite erhalten Sie verwenden, die Dinge in Zukunft ändern könnten, und es wird sicherlich zu einer anderen Datenbank erschweren bewegen.

Legen Sie die Zeile mit ungültiger Flagge von einer Art, die ID-Route, bearbeitet, je nach Bedarf, löschen, falls erforderlich oder als gültig markieren. Das und nicht über Lücken in der Folge Sorge

BTW, müssen Sie herausfinden, wie der ungültigen Teil selbst zu tun. etwas wie NULL-Kennzeichnung auf den Besonderheiten je funktionieren kann.

Edit: Wenn Sie können, Eevee Vorschlag der Verwendung richtige Transaktionen verwenden. Es ist viel weniger Arbeit.

Ich weiß, Ihre Anwendung SQLite ist klein und SQLite hat seine eigene Semantik. Andere Lösungen, die hier erstellt haben, können auch den Effekt haben, dass Sie in diesem speziellen Einstellung wollen, aber meiner Meinung nach jeder einzelne von ihnen, dass ich bisher gelesen habe, ist grundlegend falsch und sollte vermieden werden.

In einer normalen Umgebung eine Transaktion für die Benutzereingabe halten sollte unter allen Umständen vermieden werden. Die Art und Weise, dies zu umgehen, wenn Sie Zwischendaten speichern müssen, ist es, die Informationen zu einem Kratzer Tabelle für diesen Zweck zu schreiben und dann versuchen, alle Informationen in einer atomaren Transaktion zu schreiben. Transaktionen lädt Deadlocks und Parallelität Alpträume in einer Mehrbenutzerumgebung zu halten.

In den meisten Umgebungen können Sie keine Daten über SELECT innerhalb einer Transaktion ist wiederholbar abgerufen nehmen. Zum Beispiel

SELECT Balance FROM Bank ...
UPDATE Bank SET Balance = valuefromselect + 1.00 WHERE ...

Im Anschluss den Wert der Balance AKTUALISIEREN auch geändert werden kann. Manchmal kann man dieses Problem umgehen, indem Sie die Zeile Aktualisierung (n) Ihr Interesses an der Bank zunächst innerhalb einer Transaktion, da dies gewährleistet wird, um die Reihe zu verhindern weiteres Updates ändert seinen Wert zu sperren, bis die Transaktion abgeschlossen ist.

Aber manchmal eine bessere Möglichkeit, Konsistenz in diesem Fall, um sicherzustellen, ist Ihre Annahmen über den Inhalt der Daten in der WHERE-Klausel des Updates zu überprüfen und Zeilenanzahl in der Anwendung überprüfen. In dem obigen Beispiel, wenn Sie „UPDATE Bank“ die WHERE-Klausel den erwarteten aktuellen Wert der Balance bieten sollten:

WHERE Balance = valuefromselect

Wenn die erwartete Gleichgewicht nicht mehr passt ebenso wenig wie die WHERE-Bedingung - UPDATE tut nichts und rowcount 0 zurück Hier erfahren Sie es eine Gleichzeitigkeit Problem war, und Sie müssen erneut den Vorgang erneut ausführen, wenn etwas anderes versuchen, nicht zu ändern Ihre Daten zur gleichen Zeit.

select max(id) from particular_table is unreliable for the reason below..

http://www.sqlite.org/autoinc.html

"Der normale ROWID Auswahlalgorithmus oben beschrieben monoton einzigartige ROWIDs Erhöhung erzeugen, solange Sie nie den maximalen ROWID-Wert verwenden, und Sie nie den Eintrag in der Tabelle mit dem größten ROWID löschen. Wenn Sie jemals Zeilen löschen oder wenn Sie jemals eine Zeile mit den maximal möglichen ROWID schaffen, dann ROWIDs aus zuvor gelöschten Zeilen wiederverwendet werden kann, wenn neue Zeilen erstellen und erstellt ROWIDs neu nicht in streng aufsteigenden Reihenfolge sein könnte. "

Ich denke, dies nicht getan werden kann, weil es keine Möglichkeit sicher sein, dass nichts zwischen Ihnen bekommen eingefügt zu fragen und Sie einfügen. (Sie könnten in der Lage sein, um die Tabelle zu sperren, um fügt aber Yuck)

BTW habe ich nur verwendet, MySQL, aber ich glaube nicht, das wird keinen Unterschied machen)

Wahrscheinlich sollten Sie in der Lage sein, die neueste ID +1. Ich würde überhaupt aussehen (geht eine Weile zurück) der bestehenden IDs in der geordneten Tabelle .. Sind sie konsistent und ist jeder IDs Reihe ist eine mehr als die letzte? Wenn ja, werden Sie wahrscheinlich in Ordnung sein. Ich würde jedoch eine Kommentare im Code Erklärung der Annahme verlassen. Eine Sperre tut Garantie helfen, dass Sie nicht zusätzliche Zeilen bekommen, während Sie dies auch tun.

die last_insert_rowid () Wert auswählen.

Die meisten von allem, was gesagt werden muss in diesem Thema bereits ... jedoch sehr vorsichtig sein Rennbedingungen , wenn dies zu tun. Wenn zwei Menschen beide öffnen Ihre Anwendung / Homepage / was auch immer, und einer von ihnen eine Reihe fügt hinzu, versucht der andere Benutzer eine Zeile mit der gleichen ID einfügen, und Sie werden viele Probleme haben.

select max(id) from particular_table;

Die nächste id wird ein von der maximalen ID.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top