helmuthelmut2000
Goto Top

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.

Content-Key: 179124

Url: https://administrator.de/contentid/179124

Printed on: April 19, 2024 at 21:04 o'clock

Mitglied: 88871
88871 Jan 18, 2012 at 13:22:41 (UTC)
Goto Top
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;


if($jetzt < $datumsfeld)
{
echo "Leider ist das Datum noch nicht überschritten :)";  
}
else
{
schreibe in das neue msssql feld etwas;
}
Member: Arano
Arano Jan 18, 2012 at 14:49:27 (UTC)
Goto Top
Hi

Das kann man auch gleich von der DB erledigen lassen ! (Kenne MSSQL nicht)

Pseudocode:
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
Member: helmuthelmut2000
helmuthelmut2000 Jan 18, 2012 at 21:20:19 (UTC)
Goto Top
Hallo,

Die variante gefällt mir sehr gut und ich hab das mal so versucht.
Bei mir kommt aber folgende Fehlermeldung:

Warning: mssql_query() [function.mssql-query]: message: Falsche Syntax in der Nähe von '00'. (severity 15) in C:\

Meine Datum in der DB werden so gespeichert.

2011-12-29 00:00:00.000

Wo könnte da noch ein Fehler sein?

Danke
Member: Arano
Arano Jan 19, 2012 at 15:56:43 (UTC)
Goto Top
Hm... wie sieht den der Query aus !?
Member: Biber
Biber Jan 19, 2012 at 16:32:00 (UTC)
Goto Top
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
UPDATE `tabelle`
   SET `anderesFeld` = 'unbekannter Wert'  
 WHERE `datum` <= NOW()    
      AND `anderesFeld` is NULL

...lieber so herum..
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
Member: Arano
Arano Jan 19, 2012 at 16:58:53 (UTC)
Goto Top
Hallo 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?
Also ähm, ich denke schon aber sicher bin ich mir jetzt nicht mehr -.-
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":
Zitat von PONS.eu - volatil
vo-la-til ADJ. (lat.)
verdunstend; flüchtig
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
Member: helmuthelmut2000
helmuthelmut2000 Jan 20, 2012 at 11:35:12 (UTC)
Goto Top
Hallo,

Ich hätte jetzt noch etwas hilfe gebraucht wo genau schreib ich das rein.
Meine Seite schaut jetzt so aus.

$db_link=mssql_connect(MSSQL_HOST,MSSQL_USER,MSSQL_PASS);
$select=mssql_select_db(MSSQL_DATABASE);

  $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'");  
  $num = mssql_num_rows($res);
Dann kommt die Tabelle wo mir die ganzen Zeilen angezeigt werden.
echo "<table>";  
echo '<tr>";  
echo "<td class='td1 tdcenter'>" . $dsatz["abt"] . "</td>";  
echo "<td class='td2 tdcenter'>" . $dsatz["datum"] . "</td>";  
echo "</tr>";  
echo "</table>";  

Dann wird die Seite alle 90sec aufgefrischt mit:

<meta http-equiv="refresh" content="90">  

Jetzt kommt da ein Feld dazu das heist markierung und in der db heist das auch markierung.
und alle 90sec oder wenn die Seite aufgerufen wird sollte auch das datum das jetzt in dem Feld datum steht
kontrolliert werden, und wenn es vorbei ist dann sollte in das Feld markierung ein Eintrag geben.

Wo genau schreibe ich den code rein?
Member: Arano
Arano Jan 20, 2012 at 23:23:52 (UTC)
Goto Top
Hi,

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:
<?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
Member: helmuthelmut2000
helmuthelmut2000 Jan 22, 2012 at 12:16:57 (UTC)
Goto Top
Hallo,

Ich bekomme jetzt noch den Fehler:
Behandle den Fehlerfall
und es macht auch noch nix.

Kann man das noch etwas genauer anzeigen lassen, wo der Fehler liegt?

Wie sollte denn das datum Feld in der DB Formatiert sein? date oder datetime?

Und wie sollte es Richtig angelegt sein damit das funktioniert?

Gruß
Helmut
Member: Arano
Arano Jan 22, 2012 at 14:07:12 (UTC)
Goto Top
Moin.

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 !
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.
$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();
} 
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
Member: helmuthelmut2000
helmuthelmut2000 Jan 22, 2012 at 16:01:28 (UTC)
Goto Top
Hallo Arano,

Danke erstmal für die gute Erklärung.

Jetzt bekomme ich noch die Fehlermeldung:

1. Behandle den Fehlerfall
2. Notice: Undefined variable: mssql_error in C:\Apache\htdocs\...... .php on line 288
3. Fatal error: Function name must be a string in C:\Apache\htdocs\...... .php on line 288


Gruß
Helmut
Member: Arano
Arano Jan 22, 2012 at 16:18:53 (UTC)
Goto Top
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:
echo '<b>Fehlermeldung:</b><br>'.$mssql_error().'<br><br>';   
  1. Sollte es "mssql_error()" heißen (sollte ja ein Funktionsaufruf zur Ausgabe der DB-Fehlermeldung sein), daher die Fehlermeldungen Nr 2 und 3
  2. 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
Member: helmuthelmut2000
helmuthelmut2000 Jan 22, 2012 at 16:46:41 (UTC)
Goto Top
Hallo,


echo 'Fehlermeldung:<br>'.mssql_get_last_message().'<br><br>';

Dann bekomm ich die Meldung:


Falsche Syntax in der Nähe von '<'.
Member: Arano
Arano Jan 22, 2012 at 17:15:49 (UTC)
Goto Top
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.
  • 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
Member: helmuthelmut2000
helmuthelmut2000 Jan 22, 2012 at 19:11:01 (UTC)
Goto Top
Hallo,

Hab ich da ein Fehler beim auslesen vomdatum.

$strQueryUpdTabMarks = "UPDATE Ergebnisse SET markieren = '#555555' WHERE markieren is NULL AND " . $dsatz["datum"] . " <= GETDATE()";

Wenn ich das Probiere mit der Zeile.

echo "" . $dsatz["datum"] . "";

Dann kommt es so raus.

22/jan/2012 0:00

Ist da was nicht Richtig?
Member: Arano
Arano Jan 22, 2012 at 19:34:57 (UTC)
Goto Top
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:
...
WHERE markieren is NULL
  AND " . $dsatz["datum"] . " <= GETDATE()  
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:
...
AND `datumsFeldDerTabelleVomTypeDATETIME` <= GETDATE()
um alle Datensätze zu treffen, die älter als "jetzt" sind.


~Arano
Member: helmuthelmut2000
helmuthelmut2000 Jan 26, 2012 at 13:02:49 (UTC)
Goto Top
Hallo Arano,

Jetzt gehts.

Da war mein Fehler, so muss es aussehen:

AND datum <= GETDATE()

Wie schreibt man das wenn ich den Heutigen Tag nicht mit markieren will?
Kann man das an das datum plus einen Tag mit dranschreiben?

Danke.
Member: Arano
Arano Jan 26, 2012 at 16:14:05 (UTC)
Goto Top
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:
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
Member: helmuthelmut2000
helmuthelmut2000 Jan 26, 2012 at 20:35:02 (UTC)
Goto Top
Hallo Arano,

Mein datum Feld hat den Typ datetime. Die Datum stehen da alle mit dem Zeitwert 00:00:00.

Mich hätte das mal interessiert ob das überhaupt geht, das mit z.B. 1 Tag dazu Zählen.
Meine Überlegung ist noch ob ich evt. 2Tage vor dem Datum eine Farbe mach und dann 1Tag vorher in eine andere
und dann am Tag wo im datum Feld steht wieder eine andere.

Deshalb wollte ich mal einen Tag dazu Zäheln.

Danke.

Gruß
Helmut
Member: Arano
Arano Jan 26, 2012 at 21:00:09 (UTC)
Goto Top
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
Member: helmuthelmut2000
helmuthelmut2000 Jan 27, 2012 at 14:00:31 (UTC)
Goto Top
Hallo Arano,

Jetzt hab ich es hinbekommen.
So muß das aussehen:

WHERE DATEADD(day,1,datum) <= GETDATE()

Danke.