ich arbeite bereits seit einiger Zeit mit PostgreSQL und bin nach wie vor begeistert von den Sequenzen.
Ich habe in einem Teil meines Programms eine Auftragseingabe. Der Kunde möchte hierbei die automatisch vergebene Auftragsnummer bereits während der Eingabe sehen. Das ist kein Problem, sobald ich das Formular für die Eingabe öffne hole ich mir den nächsten Wert aus der Sequenz und zeige den einfach mit an.
Das Funktioniert sehr gut, da das Programm so ausgelegt ist, dass es für jedes Fenster eine eigene Verbindung zur Datenbank herstellt können auf diese Weise selbst am selben PC (auf verschiedenen sowieso) mehrere Aufträge gleichzeitig zur Eingabe geöffnet sein, ohne dass es Probleme mit der Nummer gibt.
Es gibt nur ein einziges Problem: Sobald jemand das Formular öffnen und die Auftragseingabe abbricht gibt es eine Lücke in der Sequenz. Die Nummer wurde ja schon aus der Sequenz heraus vergeben zum anzeigen, der Datensatz aber nicht gespeichert. Der Kunde möchte aber aus internen Gründen keine Lücken in der fortlaufenden Nummer der Aufträge.
Kennt hier jemand eine Möglichkeit wie ich eine Sequenz so anlegen kann, dass sie keine Lücken aufweist?
Bisher funktioniert eine Sequenz ja so, dass der nächste Wert gezogen wird.
Ich möchte nun aber eine die den kleinsten freien Wert nimmt.
Vielen Dank für den Link,
das gab ja ein paar gute Hinweise
Leider muss ich mir wohl doch komplett selber helfen, ich hatte gehofft, dass es da noch irgend eine versteckte Funktion in Postgre gibt.
Ich werd wohl entsprechend mit Triggern arbeiten müssen, da es auch vorkommen kann, dass ein Auftrag nachträglich gelöscht wird, und dann soll die Auftragsnummer wieder “frei” sein und belegt werden können.
Ich werd wohl entsprechend mit Triggern arbeiten müssen, da es auch vorkommen kann, dass ein Auftrag nachträglich gelöscht wird, und dann soll die Auftragsnummer wieder “frei” sein und belegt werden können.
Ich hab von Buchhaltung nich viel Plan, nur so viel, daß ich weiß, daß man da wohl eher einen Stornoauftrag macht. Vermutlich bekommst Du mit dem Finanzamt massiv Ärger, wenn in fortlaufenden Nummern (Rechnung, Auftrag) das Datum ‘springt’.
Soviel ich weiss kommt es dem FA nur auf eine fortlaufende Rechnungsnummer an, und das ist ja auch sichergestellt.
Das es keine Lücken in den Auftragsnummern geben soll kann ich, ausgehend vom Kunden, auch verstehen.
Das Hauptproblem liegt ja darin, dass eine Auftragnummer die bereits “angezeigt” wird nicht vergeben wird weil die Auftragseingabe (und damit die Transaktion) abbricht.
Ich werd mir also etwas bauen um an die kleinstmögliche freie Nummer zu kommen. So schließe ich das recht gut aus.
Also Auftragsnummern sind egal, die interessiert das FA nicht (meines Wissens). Für Aufträge gibt es nicht direkt Geld, erst für die Rechnung, die daraufhin geschrieben wird. Da lasse ich mich aber noch gerne umbelehren.
Wichtig ist, das du fortlaufende Rechnungsnummern vorweisen kannst bzw. nachweisen kannst, wo Lücken in deinen Rechnungsnummern herkommen. Also storniert man Rechnungen, wie akretschmer schon gesagt hat, und löscht sie nicht.
Warum gehst du das ganze also nicht von hinten an und vergibst erst die Rechnungsnummer, wenn die Rechnung (in die Datenbank) geschrieben wird? Dann bist du erst mal deinen Satz Probleme los.
Du könntest übrigens auch Probleme bekommen, wenn deine eine Rechnung Nr. 3 am Freitag im Februar und die Rechnung Nr. 2 am Montag im März geschrieben wurde, weil du eine Lücke aufgefüllt hast.
Das wäre dann keine “fortlaufende” Numerierung sondern sagt dem Sachbearbeiter, der dich besuchen kommt, sehr eindeutig, das hier offensichtlich Rechnungen fehlen. Die wird er dann von dir sehen wollen und du kannst sie nicht vorweisen …
hier in Firma läuft es so, daß bei einem Auftrag der Kunde eine Auftragsbestätigung bekommt, und diese ist fortlaufend ohne Lücke und ist dann später auch die Rechnungsnummer. So kann man auch schön schnell zu einer Rechnung den Auftrag finden. Vielleicht mal so als Hint…
Genau so gehe ich bei Rechnungsnummer doch auch vor…
Eine Löschfunktion für Rechnungen wird es daher natürlich auch niemals geben.
Um die geht es hier ja auch gar nicht, sondern um das generieren von Auftragsnummern
Ich fang mal anders an:
Der Kunde möchte, dass in dem Augenblick wo er beginnt einen neuen Auftrag zu erfassen die Auftragsnummer bereits auf dem Bildschirm zu erkennen ist.
Der Grund dafür ist, dass der Kunde nach dem Erfassen des Auftrags auf die Vorlage (ein Fax von dessen Kunden oder ein Zettel auf dem das ganze notiert ist) die Auftragsnummer schreiben möchte bevor er diese in den großen Karton wirft.
Die Vorgabe ist halt so und da kann ich nicht dran rütteln. Ich hab auch schon probiert durchzusetzen, dass die Auftragsnummer erst dann angezeigt wird sobald der Auftrag der Datenbank übergeben und gedruckt wird. Das reicht dem Kunden aber leider nicht. Frei nach der Devise: “Das war früher auch immer so, das muss so bleiben.”
Ich habe das ganze ja auch entsprechend umgesetzt. Schwierigkeiten gab es an sich nie, nur Lücken in der fotlaufenden Nummer sobald jemand die Auftragseingabe abbrach.
Nun möchte der Kunde aber, dass diese Auftragsnummer nach Möglichkeit fortlaufend ist, damit er danach Ablegen kann.
Wenn es “nur” um Auftragsnummern geht und das FA dabei keine Rolle spielt, kannst du dich die Nummern intern reservieren, z.B. mit einem Status “reserviert” aus der DB holen und wenn das fehlschlägt, weisst du, warum die Nummer weg ist. Das lässt sich nachprüfen und für interne Vorgänge reicht das, denke ich.
Wo du beim Wiederverwerten ansonsten Probleme bekommen könntest: Arbeitsplatz 1 will Auftrag erstellen, holt die erste freie Nummer. Arbeitsplatz 2 fängt an, bekommt die gleiche Nummer, weil die ist ja immer noch frei! Einer der beiden schliesst seinen Auftrag ab … bummer
Richtig, das wäre ein Problem.
Ich habe es jetzt ganz einfach aus der Anwendung heraus gelöst.
Ich habe nun eine Tabelle in der die Auftragsnummer entsprechend hochgezählt wird. Ein SELECT … FOR UPDATE sorgt dafür, dass jeder Client auch nur eine bekommt wenn er sie daraus abfragt.
Daneben hab ich noch eine Tabelle in der alle Nummer eingetragen werden, sollte die Eingabe abgebrochen werden (da sie ganz zu beginn der Eingabe hier vorsichtshalber schon einmal eingetragen wird steht sie auch auf jeden Fall drin auch wenn der Client nicht regulär Abbricht).
Bei einer Neueingabe prüfe ich also erst ob in der Tabelle mit abgebrochenen Nummern etwas steht und verwende dort die kleinste Nummer falls etwas drin steht, ansonsten nehme ich die aus der Tabelle die die nächste Nummer bereithält und erhöhe deren Wert um 1.
Wenn das eine Webanwendung ist, wird dies dein Problem nicht lösen.
Wenn das eine normale Applikation ist, wird der zweite Arbeitsplatz solange in dem SELECT hängen, bis der erste die Daten freigibt. Weil der zweite ja eigentlich die Daten braucht, die da drinstehen.
Wie ads schon sagte, das select … for update macht dann ja nur einen Sinn, wenn das in einer TX abläuft. Bei einer Web-App wirst Du wahrscheinlich das nicht haben, bei einer normalen App in, ich sach mal, Tcl/Tk, sperrt das dann den/die anderen Clients bis zum commit/rollback.
Da kommst Du vielleicht besser, du druckst am Tagesende via Cron für alle fehlenden Nummern ein Blatt, wo die Nummer drauf steht sowie: “wie sie sehen, sehen sie nix” und man verwendet das zur Ablage…
Ich werde hier nochmal ein wenig rumtesten, bisher sieht es ganz gut aus.
Ich poste heute Abend wie genau ich es gelöst habe, vielleicht kann es ja jemand anders mal gebrauchen.
Vielleicht kann man meine Methode die ich ja auf Anwendungsseite umsetze auch irgendwie direkt in die Datenbank integrieren. Ich weiss aber nicht ob das einen Vorteil in Sachen Geschwindigkeit bringen würde.
Schaun wir mal
Bei der Anwundung handelt es sich um keinerlei Webanwendung sondern eine in Java geschriebene ganz normale Anwendung.