Wenn ein Datum aktuell oder erreicht ist, sollte in ein DB-Feld geschrieben werden.
Hallo,
Ich habe eine PHP-Seite und eine MSSQL-DB.
Da gibt es ein Datum Feld (Datetime) wo ein Datum und Uhrzeit reingeschrieben wird.
Jetzt hätte ich gern, das wenn das Datum jetzt mit dem aktuellen Datum übereinstimmt oder abgelaufen ist,
sollte in ein anderes DB-Feld etwas geschrieben werden.
Wie realisiert man das am besten?
Danke.
Ich habe eine PHP-Seite und eine MSSQL-DB.
Da gibt es ein Datum Feld (Datetime) wo ein Datum und Uhrzeit reingeschrieben wird.
Jetzt hätte ich gern, das wenn das Datum jetzt mit dem aktuellen Datum übereinstimmt oder abgelaufen ist,
sollte in ein anderes DB-Feld etwas geschrieben werden.
Wie realisiert man das am besten?
Danke.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 179124
Url: https://administrator.de/forum/wenn-ein-datum-aktuell-oder-erreicht-ist-sollte-in-ein-db-feld-geschrieben-werden-179124.html
Ausgedruckt am: 15.04.2025 um 15:04 Uhr
21 Kommentare
Neuester Kommentar

Mein Vorschlag:
1. Du setzt alles in Variablen.
2. "jedesmal beim aufruf deiner seite" vergleichst du die dann mit Grösser/Kleiner (< >)
3. und agierst dann danach....
bsp:
// variablen setzen
$jetzt = datumFormat mit php. warum habt ihr keine unixtime? viel einfacher zum handlen als date/time, anyway;
$datumsfeld = query zu deiner msssql;
1. Du setzt alles in Variablen.
2. "jedesmal beim aufruf deiner seite" vergleichst du die dann mit Grösser/Kleiner (< >)
3. und agierst dann danach....
bsp:
// variablen setzen
$jetzt = datumFormat mit php. warum habt ihr keine unixtime? viel einfacher zum handlen als date/time, anyway;
$datumsfeld = query zu deiner msssql;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
if($jetzt < $datumsfeld)
{
echo "Leider ist das Datum noch nicht überschritten :)";
}
else
{
schreibe in das neue msssql feld etwas;
}
Hi
Das kann man auch gleich von der DB erledigen lassen ! (Kenne MSSQL nicht)
Pseudocode:
NOW() heißt es in MySQL, für MsSQL müsste es, glaube ich, GETDATE() heißen.
AND `anderesFeld` = NULL ist wichtig, sonst würden natürlich auch alle "alten" Datensätze bearbeitet werden bei denen der Wert schon gesetzt ist. Sonst werden deren Werte immer mit neuen/aktuellen überschrieben - das kann man sich ja auch sparen...
~Arano
Das kann man auch gleich von der DB erledigen lassen ! (Kenne MSSQL nicht)
Pseudocode:
1
2
3
4
2
3
4
UPDATE `tabelle`
SET `anderesFeld` = 'unbekannter Wert'
WHERE `datum` <= NOW()
AND `anderesFeld` = NULL
NOW() heißt es in MySQL, für MsSQL müsste es, glaube ich, GETDATE() heißen.
AND `anderesFeld` = NULL ist wichtig, sonst würden natürlich auch alle "alten" Datensätze bearbeitet werden bei denen der Wert schon gesetzt ist. Sonst werden deren Werte immer mit neuen/aktuellen überschrieben - das kann man sich ja auch sparen...
~Arano
Moin Arano,
bist du sicher, dass der Vergleich "`WHERE anderesFeld` = NULL" akzeptiert wird?
Wäre nicht ein "WHERE IFNull(`anderesFeld`) oder am lesbarsten "WHERE `anderesFeld` is NULL" angemessener?
Abgesehen davon würde ich die beiden WHERE-Filter umdrehen.
Also statt
...lieber so herum..
-> denn im Lauf der Zeit wird sicherlich eine Prüfung auf "`anderesFeld` is NULL" viel selektiver sein (die meisten `anderesFeld` sind ja schon mit Werten gefüllt).
Wird zuerst das Datumsfeld geprüft , dann muss ja jeder Datensatz verglichen werden mit jedesmal dem (volatilen) Wert von NOW().
Das dürfte teurer sein, jedenfalls wenn auf keinem der Felder ein index liegt.
Grüße
Biber
bist du sicher, dass der Vergleich "`WHERE anderesFeld` = NULL" akzeptiert wird?
Wäre nicht ein "WHERE IFNull(`anderesFeld`) oder am lesbarsten "WHERE `anderesFeld` is NULL" angemessener?
Abgesehen davon würde ich die beiden WHERE-Filter umdrehen.
Also statt
1
2
3
4
2
3
4
UPDATE `tabelle`
SET `anderesFeld` = 'unbekannter Wert'
WHERE `datum` <= NOW()
AND `anderesFeld` is NULL
...lieber so herum..
1
2
3
4
2
3
4
UPDATE `tabelle`
SET `anderesFeld` = 'unbekannter Wert'
WHERE `anderesFeld` is NULL
AND`datum` <= NOW()
-> denn im Lauf der Zeit wird sicherlich eine Prüfung auf "`anderesFeld` is NULL" viel selektiver sein (die meisten `anderesFeld` sind ja schon mit Werten gefüllt).
Wird zuerst das Datumsfeld geprüft , dann muss ja jeder Datensatz verglichen werden mit jedesmal dem (volatilen) Wert von NOW().
Das dürfte teurer sein, jedenfalls wenn auf keinem der Felder ein index liegt.
Grüße
Biber
Hallo Biber,
Also wenn es NULL als Standardwert hat, dann... ach Mist !
Das muss ich mir irgendwann mal genauer anschauen.
"volati":
Das musste ich erst mal nachschlagen.
Also NOW() liefert zwar immer den selben Zeitwert (the time at which the statement began to execute), berechnet ihn aber für jeden Vergleich auf ein neues !?
~Arano
bist du sicher, dass der Vergleich "`WHERE anderesFeld` = NULL" akzeptiert wird?
Wäre nicht ein "WHERE IFNull(`anderesFeld`) oder am lesbarsten "WHERE `anderesFeld` is NULL" angemessener?
Also ähm, ich denke schon aber sicher bin ich mir jetzt nicht mehr -.-Wäre nicht ein "WHERE IFNull(`anderesFeld`) oder am lesbarsten "WHERE `anderesFeld` is NULL" angemessener?
Also wenn es NULL als Standardwert hat, dann... ach Mist !
Das muss ich mir irgendwann mal genauer anschauen.
Abgesehen davon würde ich die beiden WHERE-Filter umdrehen.
Jetzt wo du es sagst - ich auch :D"volati":
Das musste ich erst mal nachschlagen.
Also NOW() liefert zwar immer den selben Zeitwert (the time at which the statement began to execute), berechnet ihn aber für jeden Vergleich auf ein neues !?
Das dürfte teurer sein, jedenfalls wenn auf keinem der Felder ein index liegt.
Stimmt.~Arano
Hi,
An welcher Stelle, am besten wohl an eine Stelle __bevor__ du die aktualisierten Daten abrufst/brauchst.
ich vermute mal das es zwischen dem DB-Select und deinem erstem Query kommt:
Schönes Wochenende
~Arano
Wo genau schreibe ich den code rein?
Na, da es ein Statement ist, muss es natürlich an die Datenbank übergeben werden, damit diese das ausführen kann.An welcher Stelle, am besten wohl an eine Stelle __bevor__ du die aktualisierten Daten abrufst/brauchst.
ich vermute mal das es zwischen dem DB-Select und deinem erstem Query kommt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$select=mssql_select_db(MSSQL_DATABASE);
// Aktualisiere Datensatzmarkierungen unter Bedingungen X, Y und Z
$strQueryUpdTabMarks = "UPDATE `tabelle`
SET `markierung` = 'x'
WHERE `markierung` is NULL
AND `datum` <= NOW()";
$bolUpdTabMarks = @mssql_query($strQueryUpdTabMarks);
if( FALSE===$bolUpdTabMarks )
{
echo 'Behandle den Fehlerfall';
// zeige Fehlerseite, was auch immer...
exit();
}
// Jetzt lese die aktualisierten Daten aus der Datenbank
$res = mssql_query("SELECT *, SUBSTRING(CONVERT(VARCHAR(8), erhalten,4),1,8) AS erhalten,
SUBSTRING(CONVERT(VARCHAR(8), datum,4),1,6) AS datum from Ergebnisse WHERE abt = '2'");
// Dein weitere Quelltext
?>
Schönes Wochenende
~Arano
Moin.
Wenn du das Feld als Typ "date" definierst, dann wird z.B. bei allem von Heute die Markierung gesetzt - auch bei denen von heute Abend, denn das Datum ist das gleiche.
Wenn du das Feld aber vom Typ "datetime" definierst, ist das Logischerweise noch von der Uhrzeit abhängig und es wird nur das markiert, was ÄLTER als JETZT ist. Alles was noch in der Zukunft liegt (und sei es nur eine Sekunde) bleibt unberührt.
Jetzt könnte man noch mal überlegen ob "datetime" oder "timestamp"...
"datetime" verbraucht zwar mehr Speicherplatz 8bytes und "timestamp" nur 4bytes dafür kann man den Timestamp schlecht lesen und müsste ihn für die Ausgabe erst formatieren lassen.
"date" wiederum verbraucht nur 3 bytes...
MySQL - Reference: 10.5. Data Type Storage Requirements
Richtiges Wissen darüber habe ich allerdings auch nicht, würde mich dennoch, sofern der Datums-/Zeitwert nicht ausgegeben wird für "timestamp" entscheiden.
Funktionieren sollte es aber mit allen dreien (beachte logische Einschränkungen beim Type "date")
Und das nur "Behandle den Fehlerfall" ausgegeben wird und sonst nichts weiter Passiert haben wir ja so geschrieben (exit();)
Nun, jetzt sollten wir uns, zumindest für den Moment, noch ein paar Zusatzangaben ausgeben lassen, z.B.: Das Query das den Fehler verursacht hat / beteiligt ist und die Fehlermeldung von der Datenbank.
Wie gesagt, __nur für den Moment__, den den Benutzer interessieren diese hässlichen Fehlermeldungen nicht - falls er sie überhaupt versteht. ;)
Das exit() ist natürlich auch nicht schön (einfach so "abzuwürgen") aber ein weiterarbeiten, ohne aktualisierte Daten macht vermutlich auch nicht viel Sinn !?
~Arano
Wie sollte denn das datum Feld in der DB Formatiert sein? date oder datetime?
Das ist natürlich von dem Verwendungszweck abhängig !Wenn du das Feld als Typ "date" definierst, dann wird z.B. bei allem von Heute die Markierung gesetzt - auch bei denen von heute Abend, denn das Datum ist das gleiche.
Wenn du das Feld aber vom Typ "datetime" definierst, ist das Logischerweise noch von der Uhrzeit abhängig und es wird nur das markiert, was ÄLTER als JETZT ist. Alles was noch in der Zukunft liegt (und sei es nur eine Sekunde) bleibt unberührt.
Jetzt könnte man noch mal überlegen ob "datetime" oder "timestamp"...
"datetime" verbraucht zwar mehr Speicherplatz 8bytes und "timestamp" nur 4bytes dafür kann man den Timestamp schlecht lesen und müsste ihn für die Ausgabe erst formatieren lassen.
"date" wiederum verbraucht nur 3 bytes...
MySQL - Reference: 10.5. Data Type Storage Requirements
Richtiges Wissen darüber habe ich allerdings auch nicht, würde mich dennoch, sofern der Datums-/Zeitwert nicht ausgegeben wird für "timestamp" entscheiden.
Funktionieren sollte es aber mit allen dreien (beachte logische Einschränkungen beim Type "date")
Ich bekomme jetzt noch den Fehler:
Behandle den Fehlerfall
und es macht auch noch nix.
Okay, da liegt wohl noch ein Fehler im Query !Behandle den Fehlerfall
und es macht auch noch nix.
Und das nur "Behandle den Fehlerfall" ausgegeben wird und sonst nichts weiter Passiert haben wir ja so geschrieben (exit();)
Nun, jetzt sollten wir uns, zumindest für den Moment, noch ein paar Zusatzangaben ausgeben lassen, z.B.: Das Query das den Fehler verursacht hat / beteiligt ist und die Fehlermeldung von der Datenbank.
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
$bolUpdTabMarks = @mssql_query($strQueryUpdTabMarks);
if( FALSE===$bolUpdTabMarks )
{
echo 'Behandle den Fehlerfall';
// zeige Fehlerseite, was auch immer...
// +++
echo '<b>Fehlermeldung:</b><br>'.$mssql_error().'<br><br>';
echo '<b>Query:</b><br><pre>'.$sql.'</pre>';
exit();
}
Das exit() ist natürlich auch nicht schön (einfach so "abzuwürgen") aber ein weiterarbeiten, ohne aktualisierte Daten macht vermutlich auch nicht viel Sinn !?
~Arano
Hi
Hm... ich hätte jetzt etwas andere Ausgaben erwartet, z.B. noch den Query...
Aber hier habe ich z.B. gleich zwei Fehler gemacht:
Schau mal hier nach dem MSSQL Pendant: PHP-Manual - Mssql-Funktionen
Es erfreut mich das du meine Bemühungen annimmst, jedoch... etwas Eigeninitiative deinerseits wäre auch nicht schlecht.
Nächstes mal !
~Arano
Hm... ich hätte jetzt etwas andere Ausgaben erwartet, z.B. noch den Query...
Aber hier habe ich z.B. gleich zwei Fehler gemacht:
1
echo '<b>Fehlermeldung:</b><br>'.$mssql_error().'<br><br>';
- Sollte es "mssql_error()" heißen (sollte ja ein Funktionsaufruf zur Ausgabe der DB-Fehlermeldung sein), daher die Fehlermeldungen Nr 2 und 3
- gibt es kein "mssql_error()" *g* Das hatte ich einfach so von MySQL (mysql_error()) übernommen und abgewandelt.
Schau mal hier nach dem MSSQL Pendant: PHP-Manual - Mssql-Funktionen
Es erfreut mich das du meine Bemühungen annimmst, jedoch... etwas Eigeninitiative deinerseits wäre auch nicht schlecht.
Nächstes mal !
~Arano
Nun, diese Fehlermeldung bedeutet das etwas in dem Query nicht der Syntax entspricht in der es erwartet wird und das in der Nähe von dem Zeichen '<'.
Wie gesagt, ich habe keine Erfahrungen mit MSSQL.
Außerdem ist das, ohne den tatsächlich verwendeten Query zu sehen, immer etwas wage.
Alles was ich so noch sehe ist die falsche Funktion "NOW()" die, wie weiter oben schon mal erwähnt, MSDN - GETDATE() heißen sollte.
Allerdings ist das vermutlich nicht der Fehler denn dann müsste in der Fehlermeldung die Rede von den Zeichen "<=" sein, und nicht nur von einem Zeichen beliebig weiter vorn... *think so*
~Arano
Wie gesagt, ich habe keine Erfahrungen mit MSSQL.
Außerdem ist das, ohne den tatsächlich verwendeten Query zu sehen, immer etwas wage.
- Fehler die durchs anpassen an deine Gegebenheiten entstanden sind,
- Tippfehler
- vergessene/übersehen Zeichen
- ...
Alles was ich so noch sehe ist die falsche Funktion "NOW()" die, wie weiter oben schon mal erwähnt, MSDN - GETDATE() heißen sollte.
Allerdings ist das vermutlich nicht der Fehler denn dann müsste in der Fehlermeldung die Rede von den Zeichen "<=" sein, und nicht nur von einem Zeichen beliebig weiter vorn... *think so*
~Arano
Ohje, schon so spät !?
1. Bei einem UPDATE-Query, kommt nichts raus, höchsten TRUE oder FALSE als Rückgabewerte !
So weiss ich also schon nicht einmal mehr wo du die Zeichenkette "22/jan/2012 0:00" überhaupt her hast !?
2. Hast du da in deinem Query etwas durcheinander gebracht, in der WHERE-Klausel:
Was möchtet du denn nach dem AND vergleichen ?
Im Moment wird irgendein Datum mit dem aktuellem Datums- und Zeitwert verglichen - allerdings hat das überhaupt keinen Bezug auf die Datensätze in der Tabelle.
Und weil der Vergleich höchst wahrscheinlich immer scheitert, wird auch kein Datensatz aktualisiert !
(Noch dazu müsste die Ausgabe der Variabel in dem Query noch in Anführungszeichen stehen)
Du wolltest doch ein Feld der Tabelle vom Type "datetime" mit dem aktuellem Datums-/Zeitwert vergleichen...
also:
um alle Datensätze zu treffen, die älter als "jetzt" sind.
~Arano
1. Bei einem UPDATE-Query, kommt nichts raus, höchsten TRUE oder FALSE als Rückgabewerte !
So weiss ich also schon nicht einmal mehr wo du die Zeichenkette "22/jan/2012 0:00" überhaupt her hast !?
2. Hast du da in deinem Query etwas durcheinander gebracht, in der WHERE-Klausel:
1
2
3
2
3
...
WHERE markieren is NULL
AND " . $dsatz["datum"] . " <= GETDATE()
Im Moment wird irgendein Datum mit dem aktuellem Datums- und Zeitwert verglichen - allerdings hat das überhaupt keinen Bezug auf die Datensätze in der Tabelle.
Und weil der Vergleich höchst wahrscheinlich immer scheitert, wird auch kein Datensatz aktualisiert !
(Noch dazu müsste die Ausgabe der Variabel in dem Query noch in Anführungszeichen stehen)
Du wolltest doch ein Feld der Tabelle vom Type "datetime" mit dem aktuellem Datums-/Zeitwert vergleichen...
also:
1
2
2
...
AND `datumsFeldDerTabelleVomTypeDATETIME` <= GETDATE()
~Arano
Hallo Helmut.
Das dürfte auch kein Problem sein aber zunächst mal etwas anderes.
Ich habe nun das Problem, dass ich nicht genau weiss von welchem Typ dein Feld "datum" ist !
Dem Namen nach würde ich denken das es sich lediglich um ein Feld vom Typ "date" handelt, dann wäre die Lösung eine ganz einfache:
"Datum kleiner als Heute/Jetzt"
Das klappt aber nicht wenn das Feld vom Typ "datetime" ist, denn dann ist ja noch die Zeit mit im Spiel und ein einfaches "ist kleiner als" würde auch auf alles zutreffen das nur eine Sekunde alt ist !
Hier wäre wohl die Überlegung eines neuen Feldnamens angebracht ;)
Einfach einen Tag abziehen klappt allerdings auch nicht den der Zeitwert bliebe erhalten und wir hätten ein "datetime" von gestern __zur jetzigen Zeit__ !
Was wieder zur Folge hätte, das alles was gestern nach der jetzigen Zeit existiert NICHT berücksichtigt würde...
Genau genommen müsstest du dir also ein "datetime" erzeugen, dass das heutige Datum enthält aber den Zeitwert vom Anfang des Tages (00:00:00). Allerdings könnte es auch reichen wenn du nur das Datum hast, das weiss ich jetzt nicht - das muss du mal selber ausprobieren.
Dafür wiederum schau dir mal die Beispiele auf der MSDN - GETDATE() Seite an, da solltest du fündig werden.
MySQL zumindest macht dies mit.
~Arano
Das dürfte auch kein Problem sein aber zunächst mal etwas anderes.
Ich habe nun das Problem, dass ich nicht genau weiss von welchem Typ dein Feld "datum" ist !
Dem Namen nach würde ich denken das es sich lediglich um ein Feld vom Typ "date" handelt, dann wäre die Lösung eine ganz einfache:
WHERE `date` < GETDATE()
"Datum kleiner als Heute/Jetzt"
Das klappt aber nicht wenn das Feld vom Typ "datetime" ist, denn dann ist ja noch die Zeit mit im Spiel und ein einfaches "ist kleiner als" würde auch auf alles zutreffen das nur eine Sekunde alt ist !
Hier wäre wohl die Überlegung eines neuen Feldnamens angebracht ;)
Einfach einen Tag abziehen klappt allerdings auch nicht den der Zeitwert bliebe erhalten und wir hätten ein "datetime" von gestern __zur jetzigen Zeit__ !
Was wieder zur Folge hätte, das alles was gestern nach der jetzigen Zeit existiert NICHT berücksichtigt würde...
Genau genommen müsstest du dir also ein "datetime" erzeugen, dass das heutige Datum enthält aber den Zeitwert vom Anfang des Tages (00:00:00). Allerdings könnte es auch reichen wenn du nur das Datum hast, das weiss ich jetzt nicht - das muss du mal selber ausprobieren.
Dafür wiederum schau dir mal die Beispiele auf der MSDN - GETDATE() Seite an, da solltest du fündig werden.
MySQL zumindest macht dies mit.
~Arano
Hi.
Dein Datum ist vom Typ "datetime" - da bin ich ganz stumpf auch mal von ausgegangen weil das hier im Forum ja so erwähnt wird.
ABER warum ist der Zeitwert bei allen auf 00:00:00 !?
Wenn der IMMER Null Uhr ist, kannst du auch auf Typ "date" wechseln... sofern da nicht eben ein andere Sinn hinter steckt !?
Ja ja, das geht !
Schau doch z.B. noch einmal in die MSDN da hast du auf der linken Seite, eigentlich unübersehbar ;) , die "Datums- und Zeitfunktionen" wie z.B. DATEADD() oder DATEDIFF()
~Arano
Dein Datum ist vom Typ "datetime" - da bin ich ganz stumpf auch mal von ausgegangen weil das hier im Forum ja so erwähnt wird.
ABER warum ist der Zeitwert bei allen auf 00:00:00 !?
Wenn der IMMER Null Uhr ist, kannst du auch auf Typ "date" wechseln... sofern da nicht eben ein andere Sinn hinter steckt !?
Ja ja, das geht !
Schau doch z.B. noch einmal in die MSDN da hast du auf der linken Seite, eigentlich unübersehbar ;) , die "Datums- und Zeitfunktionen" wie z.B. DATEADD() oder DATEDIFF()
~Arano