MySQL fortlaufende Nummer mit Jahreszahl als Aktenzeichen

marcus.dietrich

Grünschnabel
Hallo,

ich benötige eure Hilfe!

In einem Formular mit PHP soll ein Aktenzeichen generiert werden, welches aus der Jahreszahl und einer fortlaufenden Nummer generiert wird. Hat jemand eine Idee?
 
Hat mit PHP nix zu tun, nur mit dem Design deiner DB.
Frage: Wie soll beim Jahressprung "weiter" gezählt werden? Soll einfach weiter gezählt werden (Bsp. "2019-4711" am 01.01.2019) oder soll wieder bei einem Startwert angefangen werden (Bsp. "2019-0001" am 01.01.2019)?
Fall 1: Kann man theoretisch den Primary Key ("ID" Auto-Increment) nehmen
Fall 2: Separates ID-Feld (zusätzlich zum PK), welches du manuell hochzählen musst bzw. beim Jahressprung wieder resetten musst
Sofern mehrere User gleichzeitig auf dieses Formular zugreifen, solltest du aber diese fortlaufende Nummer erst beim Speichern des Datensatzes erzeugen, sonst kann es zu einer Kollission kommen
 
Vorzugsweise soll beim Jahressprung wieder mit 1 begonnen werden. Die lfd. Nummer soll 6-stellig sein.

Es sollen mehrere Personen zugreifen.

Meine Vorüberlegung war, dass man eine Spalte ID, eine Spalte Jahr und eine Spalte für die lfd. Nummer hat, die dann mit Counter hochgezählt wird. Die Spalte Jahr wird mit date (nur Jahreszahl) gefüllt und von der Spalte lfd. Nummer besteht eine Beziehung zur Spalte Jahr. D. h., wenn man dann in 2019 einen Fall anlegt, soll die Spalte Jahr mit 2019 gefüllt werden und da für 2019 bisher noch keine lfd. Nummer hinterlegt ist, fängt die Spalte lfd. Nummer automatisch wieder mit 1 an. Hier kann man ggf. eine Abfrage durchführen lassen.

Ich hoffe es ist einigermaßen verständlich erklärt und nachvollziehbar.
 
Jupp, ist verständlich.
In dem Fall würde ich aber wie gesagt, die lfd. Nummer wirklich erst beim INSERT vergeben, (Kannst ja ein SELECT MAX(LfdNummer)+1 FROM MyTable WHERE Jahr=AktuellesJahr machen).
Die Spalte LfdNummer würde ich als Text anlegen, und dann per Format(LfdNummer, "000000") inkl. führende Nullen in die DB schreiben
 
Vielen Dank für eure Hinweise! Ich habe das Problem jetzt wie folgt gelöst - es funktioniert super. Ich habe es auch schon Jahresübergreifend getestet.

PHP:
<?php
    include('dbcon.php');

    $time = time();
    $year = date("Y", $time);

    $sql = "SELECT MAX(id_docket), year_docket, docket FROM lde_docket WHERE year_docket = $year";

    foreach ($pdo->query($sql) as $row);

    $lastdocket = $row['docket'];
    $docket = $lastdocket + 1;

    $sql = "SELECT * FROM lde_docket";

    $statement = $pdo->prepare("INSERT INTO lde_docket (year_docket, docket, adduser_docket) VALUES ('$year', '$docket', '$username')");

    $statement->execute(array('year_docket', 'docket', 'adduser_docket'));

    $docket = sprintf('%06d', $docket) . "/" . $year;
?>
 
es funktioniert super
Das mag sein, aber irgendwann wirst du feststellen, dass deine Datenbank rätselhaft inkonsistente (also falsche!) Inhalte aufweist, du das manuell dann reparieren darfst ;) Schlimmer noch, vielleicht hast du seit jeher auf einem falschen Datensatz gerechnet und die Ergebnisse bereits benutzt, um umumkehrbare Entscheidungen im "echten Leben" (aka. "real world actions") zu treffen.
Siehe oben:
Das hier unbedingt in eine Transaktion wickeln, sonst drohen Race Conditions.
 
Das mag sein, aber irgendwann wirst du feststellen, dass deine Datenbank rätselhaft inkonsistente (also falsche!) Inhalte aufweist, du das manuell dann reparieren darfst ;) Schlimmer noch, vielleicht hast du seit jeher auf einem falschen Datensatz gerechnet und die Ergebnisse bereits benutzt, um umumkehrbare Entscheidungen im "echten Leben" (aka. "real world actions") zu treffen.
Siehe oben:

Okay, wie funktioniert das? Könntest du mir bitte einen kleinen Ansatz aufzeigen?
 
Transaktionen sind nicht so einfach zu verstehen, insbesondere die Konsistenzbedingungen, die das DBMS dir bereitstellt. Das bedeutet: wenn zwei Transaktionen T1, T2 (= Blöcke von SQL-Anweisungen) gleichzeitig laufen, was genau sieht T1 von den Änderungen von T2?
Um korrekte Programme zu schreiben, bedarf es einiges an Einlesen in diese Thematik, das geht nicht einfach so in einer Stunde.
Ich bin da auch nicht so firm drin, weiß aber, dass es diese Problematik gibt. Bevor ich dir ein falsches Codeschnipsel für deinen konkreten Fall zeige, verweise ich da lieber auf Google.

$statement = $pdo->prepare("INSERT INTO lde_docket (year_docket, docket, adduser_docket) VALUES ('$year', '$docket', '$username')");
Übrigens ist das hier gar kein Prepared Statement, du interpolierst die Variablen direkt in den String! D.h. hier klafft eine SQL Injection Lücke. Lies am besten nocheinmal nach, wie man Prepared Statements nutzt.
 
Zurück