Beste Weg zur Generierung von Eindeutigen und fortlaufenden Nummern in Oracle
Muss ich generieren einzigartigen und aufeinander zahlen (für die Nutzung auf eine Rechnung), in eine schnelle und zuverlässige Art und Weise. derzeit verwenden eine Oracle-Sequenz, aber in einigen Fällen generierten zahlen nicht in Folge wegen der Ausnahmen, die auftreten können.
Ich dachte, ein paar von Lösungen zur Verwaltung dieses problem, aber weder Sie, mich zu überzeugen. Welche Lösung empfehlen Sie?
-
Verwenden Sie eine select max ()
SELECT MAX (NVL (doc_num, 0)) +1 FROM invoices
-
Verwenden eine Tabelle zum speichern die zuletzt generierte Zahl für die Rechnung.
UPDATE docs_numbers SET last_invoice = last_invoice + 1
-
Andere Lösung?
- Haben Sie versucht, die Zehe
NOCACHE
option aufCREATE SEQUENCE
? Das sollte beseitigen Sie die Lücken. - Nein,
NOCACHE
gibt an, wie viele Sequenz-Werte werden gespeichert-Speicher für schnelleren Zugriff: techonthenet.com/oracle/sequences.php
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den Lücken erscheinen, wenn eine Transaktion verwendet wird, eine Sequenz-Nummer, ist aber dann rollte zurück.
Vielleicht die Antwort ist nicht berechtigt, die Rechnungsnummer, bis die Rechnung kann nicht zurückgesetzt werden. Dies minimiert (aber wahrscheinlich nicht beseitigen) die Möglichkeiten der Lücken.
Ich bin mir nicht sicher, dass es keine rasche oder einfache Weise zu gewährleisten, dass keine Lücken in der Sequenz - Scans für MAX, das hinzufügen und einfügen, dass ist wahrscheinlich die am nächsten zu sichern, aber wird nicht empfohlen, aus performance-Gründen (Schwierigkeiten mit der Gleichzeitigkeit) und die Technik nicht erkennen, ob das die Letzte Rechnungsnummer zugewiesen ist, gelöscht und neu zugewiesen.
Können Sie das Konto für die Lücken, die irgendwie - durch die Identifizierung, die Rechnung zahlen wurden "gebraucht", aber "nicht dauerhaft" irgendwie? Könnte eine autonome Transaktion helfen dabei, dass?
Andere Möglichkeit - vorausgesetzt, die Lücken sind relativ wenige und weit zwischen.
Erstellen einer Tabelle, die Datensätze Sequenznummern, müssen wiederverwendet werden, bevor eine neue Sequenz Wert ist packte. Normalerweise, es würde leer sein, aber ein gewisser Prozess, der ausgeführt wird ... minute, Stunde, Tag ... überprüft Lücken und fügt die vergessene Werte in dieser Tabelle. Alle Prozesse, überprüfen Sie zuerst die Tabelle der vergessene Werte, und wenn es irgendeine vorhanden ist, verwenden Sie den Wert von dort aus, gehen durch den langsamen Prozess der Aktualisierung der Tabelle und entfernen Sie die Zeile, die Sie verwenden. Wenn die Tabelle leer ist, dann schnappen Sie sich die nächste Sequenz-Nummer.
Nicht sehr angenehm, aber die Entkopplung von 'Ausstellung Rechnung zahlen' von 'scan für verpasste Werte' bedeutet, dass selbst wenn die Rechnungsstellung Prozess schlägt fehl, wenn einige thread, wenn er mit einer der vergessene Werte, wird dieser Wert wiederentdeckt zu fehlen und wieder neu aufgelegt Nächstes mal - wiederholen, bis ein gewisser Prozess gelingt es.
1 kann jederzeit gemacht werden, fehlschlagen gewisser Weise in einer Umgebung mit gleichzeitigen
Benutzer.
2 wird funktionieren, aber wird die Grenze der Skalierbarkeit (obligatorisch Tom Kyte
Referenz:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1508205334476
Als er empfiehlt, sollten Sie wirklich überprüfen Sie die Notwendigkeit für die "keine Lücken" Anforderung
Halten die aktuelle Reihenfolge - können Sie die folgenden zurücksetzen, um den Wert auf das maximum von dem, was derzeit in der Tabelle gespeichert(en):
Beispiel wird eine anonyme sproc - ändern Sie ihn auf ordnungsgemäße Verfahren in einem Paket, und nennen Sie es vor dem einfügen einer neuen Rechnung zu halten, die Nummerierung konsequent.
Es ist nicht klar, was du meinst mit "aufgrund von Ausnahmen, die auftreten können'. Wenn Sie möchten, dass die Nummer NICHT erhöht werden, wenn Ihre Transaktion schließlich rollt sich zurück, dann FOLGE nicht zur Arbeit gehen für Sie, weil soweit ich weiß, einmal NEXTVAL angefordert wird, von der Sequenz der Sequenz-position inkrementiert und rollback nicht umkehren.
Wenn dies tatsächlich ein Anforderungen dann würde Sie wahrscheinlich zu greifen, der Speicherung Aktueller Zähler in einer separaten Tabelle, aber Vorsicht der gleichzeitige Aktualisierungen von 'lost update' und Skalierbarkeit Interessenten.
Ich denke, Sie werden feststellen, dass mit Hilfe der MAX () - von den vorhandenen zahlen ist anfällig für eine neue und spannende problem - Duplikate können auftreten, wenn mehrere Rechnungen erstellt werden, zur gleichen Zeit. (Fragt mich nicht wie ich weiß...).
Eine mögliche Lösung ist die Ableitung der primären Schlüssel, der auf Ihrer RECHNUNG Tabelle aus einer Sequenz, aber haben diese NICHT die Rechnungsnummer. Nach korrekt und ordnungsgemäß erstellen Ihre Rechnung, und nach dem Punkt, an dem eine Ausnahme oder Benutzer Laune konnte, dass die Erstellung der Rechnung gekündigt werden, Sie gehen, um eine zweite Sequenz, um die fortlaufende Nummer, die als "die" Rechnungsnummer. Dies bedeutet, dass Sie zwei eindeutige, nicht wiederholte zahlen auf Ihre RECHNUNG Tisch, und die offensichtlich einen (INVOICE_NO) wird nicht der Primärschlüssel (aber es kann und sollte EINDEUTIG sein), so dass es ein wenig böse schleichen, aber die alternative - die zur Erstellung der RECHNUNG Zeile mit einem Wert in der Primärschlüssel, dann ändern Sie die primäre Taste, nachdem Sie die RECHNUNG erstellt wird, ist einfach zu böse für die Worte. 🙂
Teilen und genießen.
Wenn Sie wirklich wollen, um keine Lücken, die Sie brauchen, um vollständig zu serialisieren zugreifen, sonst wird es immer Lücken. Die Gründe für Lücken sind:
Ich habe über dieses problem vor. In einem Fall konnten wir überzeugen, das Geschäft zu akzeptieren, dass "echte" Rechnungen könnte Lücken haben, und wir schrieb einen job, der lief jeden Tag zu "füllen" die Lücken mit "void" - Rechnungen für audit-Zwecke.
In der Praxis, wenn wir NOCACHE auf die Reihenfolge, die Anzahl der Lücken wäre relativ gering, so ist die Revisionsstelle wird in der Regel gerne, solange Ihre Abfrage über den "void" - Rechnungen nicht wieder zu viele Ergebnisse.
Haben Sie vielleicht zu überdenken, Ihren Prozess schwach und brechen Sie in mehrere Schritte. Einen nicht-transaktionalen Schritt erstellen Sie den Platzhalter Rechnung (nicht in der Transaktion sollten die Lücken zu beseitigen) und dann innerhalb der Transaktion den rest Ihres Unternehmens. Ich glaube, das war, wie wir es gemacht haben in einem system, ich steckte mit den Jahren, aber ich kann mich nicht erinnern - ich weiß nur noch, es sei "seltsam."
Ich würde sagen, dass die Reihenfolge garantiert einmalige/fortlaufende Nummern, aber wenn Sie werfen Transaktionen in der Mischung, kann nicht garantiert werden, es sei denn, die Sequenz generation, die nicht innerhalb dieser Transaktion.
dpbradley link in #2 klingt wie Ihre beste Wette. Tom hält die transactionality mit dem Anrufer, wenn Sie nicht möchten, dass Sie es schaffen könnte eine autonome Transaktion wie folgt:
Was wir tun, ist das Problem, eine Sequenznummer für die Transaktion und dann, wenn der Artikel wir sind die Verarbeitung abgeschlossen ist, geben wir eine permanente Nummer (auch die Reihenfolge).
Funktioniert gut für uns.
Hinsichtlich
K