MySQL-Abfrage mit WHERE=$variable%

tluebke

Mitglied
Hallo Leute,
ich habe im letzten Jahr ein Skript programmiert, welches automatische eine fortlaufende Nummer generieren soll. Soweit, so einfach. Jedoch soll diese Nummer Jahresabhängig sein. Im Jahr 2013 beginnen alle Nummern mit 2013 und dann folgt eine vierstellige Ziffer, aufsteigend.
Im alten Jahr hat alles gut funktioniert, doch mit dem Jahreswechsel gab es ein Problem. Ich hatte eine MySQL-Abfrage geschrieben, die schauen soll, ob es für das jeweilige Jahr bereits eine Nummer gibt, wenn ja, die höchste nehmen, +1 rechnen und dann in die neue Zeile schreiben. Im Jahr 2014 sollte aber eine neue Nummer mit 20140001 generiert werden, da keine vorherige Nummer vorhanden war.
Leider war jedoch der erste Eintrag die Nummer 20141010 (statt 20140001). Herausgefunden habe ich, dass edie if-Abfrage mit true beantwortet wird, selbst wenn die Tabelle LEER ist, also eigentlich kein Rückgabewert vorhanden sein sollte... Auch die Ausgabe von row[0] bleibt leer.
Ich habe schon das halbe Internet abgesucht (Auch die if-Abfrage verändert), aber entweder bei Google die falschen Suchbegriffe eingegeben, oder einfach nichts hilfreiches gefunden. Ich hoffe nun auf Hilfe von euch. Danke sehr.

PHP:
function getNextRechnungsnummer($db) {
  $year = date("Y");
  $result = mysql_query("SELECT MAX(eintrag) FROM $db.beitrag_total WHERE eintragsnummer LIKE'$year%'");
  if($row = mysql_fetch_row($result)) {
    $lastRunningNumber = substr($row[0], 4, 4);
    $nextRunningNumber = $lastRunningNumber + 1;
    $eintragsnummer = $year . str_pad($nextRunningNumber, 4, "0". STR_PAD_RIGHT);
    return $eintragsnummer; 
  } else {
    return $year . "0001";
  }
}
 
Ist jetzt vielleicht zu spät um noch etwas zu ändern und hilft dir auch nicht direkt beim aktuellen Problem.

Aber warum speicherst du die Jahreszahl und die eigentliche Nummer nicht in separaten Feldern.

Die Abfrage für die nächste Nummer wäre dann

SQL:
SELECT IFNULL(MAX(nummer) + 1 , 1) FROM deine_tabelle WHERE jahr = $year

Wenn MAX(nummer) + 1 den Wert NULL liefert weil es noch keinen Eintrag mit dieser Jahreszahl gibt, wird 1 zurückgegeben. Im anderen Fall wird eben gleich der erhöhte Wert zurückgegeben.
 
Das habe ich getan, damit ich nicht die beiden Felder noch verbinden muss nachträglich. Zudem wird diese Nummer noch in einer anderen Tabelle benötigt, um ein JOIN anzuwenden.
 
Diese Zeile ist falsch:

PHP:
$eintragsnummer = $year . str_pad($nextRunningNumber, 4, "0". STR_PAD_RIGHT);

so sollte es richtig sein:

PHP:
$eintragsnummer = $year . str_pad($nextRunningNumber, 4, "0", STR_PAD_LEFT);
 
Dann stellt er die 1 nach links und hängt drei Nullen ans Ende, also: 20141000. Deswegen hatte ich auch str_pad_right benutzt.

Und lösen tut es das Problem nicht, dass er die if-Abfrage mit true bewertet, obwohl sie false sein müsste.
 
Ich habe es nur rudimentär getestet, aber…

Code:
SELECT MAX(eintrag) FROM $db.beitrag_total WHERE eintragsnummer LIKE'$year%'

…liefert wohl NULL für MAX(eintrag) (und kein leeres Set), wenn keine Datensätze der Bedingung entsprechen.

Warum eigentlich MAX(eintrag) und nicht MAX(eintragsnummer)?

Vielleicht so:

Code:
SELECT eintragsnummer
FROM $db.beitrag_total
WHERE eintragsnummer LIKE'$year%'
ORDER BY eintragsnummer DESC
LIMIT 0, 1

Das sollte ein leeres Set liefern, wenn die Bedingung nicht zutrifft.

Wenn du die Nummer hast, dann vielleicht so was:

PHP:
$number = '20140001';

$tmp = str_split($number, 4);

$year      = $tmp[0];
$nextIndex = ((int) $tmp[1]) + 1;

$nextNumber = $year . str_pad($nextIndex, 4, '0', STR_PAD_LEFT);

var_dump($nextNumber);

PS: Aggregatfunktionen (MAX) nutzt man „eigentlich“ nur im Zusammenspiel mit GROUP BY. MySQL erlaubt das zwar auch so, aber das ist nicht „SQL-Standard“/hübsch.

Die mysql-Erweiterung ist veraltet. Nutze mysqli oder PDO.
 
Zuletzt bearbeitet:
Da habe ich wohl beim Abschreiben einen Fehler gemacht. Natürlich handelt es sich beim SELECT um "eintragsnummer" statt "eintrag".
Ansonsten hat mir die neue Abfrage schon sehr weitergeholfen, da sie funktioniert, wie sie soll! Danke dafür.

Wegen mysqli oder PDO muss ich mich dann wohl einlesen und die Skripte dementsprechend verändern. Auch danke für diese Info.

Und auch ein Dank an tombe: Das mit dem STR_PAD_LEFT war irgendwie doch richtig. Ich weiß nicht, warum er bei mir damit rumgezickt hatte zwischendurch.
 
Ich weiß nicht, warum er bei mir damit rumgezickt hatte zwischendurch.

Nicht überprüfte Vermutung: Du hattest da ursprünglich "0". STR_PAD_RIGHT stehen. Man beachte den Punkt (falsch) statt eines Kommas (richtig). Vielleicht stand der da auch noch in deinem Versuch mit STR_PAD_LEFT.
 
Zurück