Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi 1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern (https://www.delphipraxis.net/175111-1-sekunde-unterschied-zwischen-db-datetime-feld-und-anwendung-beim-speichern.html)

Piro 30. Mai 2013 21:29

Datenbank: MSSQL • Version: 2008 • Zugriff über: ADO

1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern
 
Moin zusammen,

ich benötige mal die Erfahrungen von euch.

Ich habe heute folgendes Phänomen bemerkt beim Speichern einer Datums- und Zeitangabe in den DB Datentyp DateTime.

Delphi-Quellcode:
lastUpdate : TDateTime

lastUpdate := now; // z.B. 2013-05-30 22:22:22

DSData.FieldbyName('lastupdate').AsDateTime := lastUpdate;
In der Datebank steht aber
Code:
2013-05-30 22:22:23
Für mich ist die Sekunde wichtig, da ich das lastupdate aus der Anwendung in einer weiteren Abfrage verwende. Durch die 1 Sekunde bekomme ich dann leider keinen Treffer.

Wie kann das denn sein? Ich merke mir bzw. speichere ja den Wert vorher in lastUpdate und danach wird er nicht mehr geändert. Das Phänomen tritt aber nicht immer auf zu 75%. Es gibt auch Fälle, wo es passt.

Hat das schon mal bemerkt und weiß wie man es abschalten kann?

Danke im Voraus.
Sven

Uwe Raabe 30. Mai 2013 21:48

AW: 1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern
 
Das könnte eine Rundungsungenauigkeit sein. Versuch es doch mal mit AsSQLTimeStamp. Alternativ alle TDateTime-Werte auf ganze Sekunden runden.

nahpets 30. Mai 2013 21:59

AW: 1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern
 
now enthält auch noch Sekundenbruchteile, das sieht momentan nach Deiner Beschreibung so aus, als würde einer abrunden und der andere aufrunden.

Daher wäre die erste Frage: Kann die Datenbank auch Sekundenbruchteile speichern?
Wenn nein, müsstes Du wohl hergehen und lastupdate auf volle Sekunden auf- oder abrunden. Das ist jetzt aber kein Wissen sondern nur eine Vermutung.

Mit
Delphi-Quellcode:
ShowMessage(FormatDatetime('dd.mm.yyyy hh:nn:ss.zzz',lastupdate));
kannst Du Dir ja mal ausgeben lassen, ob die Vermutung zutreffend sein könnte.

Uwe Raabe 30. Mai 2013 22:05

AW: 1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern
 
Zitat:

Zitat von nahpets (Beitrag 1217033)
Daher wäre die erste Frage: Kann die Datenbank auch Sekundenbruchteile speichern?

Die Genauigkeit von datetime in MSSQL 2008 ist mit 0,00333 Sekunden angegeben. Aber selbst dabei kann es zu unterschiedlichen Ergebnissen kommen.

nahpets 30. Mai 2013 22:59

AW: 1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1217034)
Zitat:

Zitat von nahpets (Beitrag 1217033)
Daher wäre die erste Frage: Kann die Datenbank auch Sekundenbruchteile speichern?

Die Genauigkeit von datetime in MSSQL 2008 ist mit 0,00333 Sekunden angegeben. Aber selbst dabei kann es zu unterschiedlichen Ergebnissen kommen.

Klar, TDateTime geht ja bis auf tausendstel Sekunden. Da bleibt genug Spielraum für Rundungsfehler.

Dann muss hier wohl lastupdate sinnvollerweise auf ganze Sekunden gerundet werden, bevor es ans Speichern und Weiterverarbeiten geht.

jensw_2000 30. Mai 2013 23:23

AW: 1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern
 
Kannst Du dir in der DB nicht einfach eine Stored Procedure anlegen, die den Datensatz in der DB aktualisiert / anhängt?
Von der SP kannst du dir den geschriebenen LastUpdate Wert nach dem Speichern als Ausgabeparameter zurückgeben lassen.
Abweichungen zwischen DB und "weiterer Verarbeitung" sind dann ausgeschlossen ...

Alternativ kannst Du Dir LastUpdate doch auch wieder zurückholen.
Aus Performancesicht ist das aber nicht ganz so optimal.

Delphi-Quellcode:
lastUpdate := now; // z.B. 2013-05-30 22:22:22
DSData.FieldbyName('lastupdate').AsDateTime := lastUpdate;
DSData.Post;
DSData.Refresh; // Daten aktualisieren, im MultiUser Betrieb hier ggf. noch prüfen ob sich die Cursorposition geändert hat
lastUpdate := DSData.FieldbyName('lastupdate').value; // natürlich noch auf NULL prüfen ..

BUG 31. Mai 2013 02:38

AW: 1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern
 
Vielleicht besteht ja auch Interesse an Notifications. Viel cooler als Polling :mrgreen:
Aber keine Ahnung wie gut das funktioniert, habe keine praktische Erfahrung mit MSSQL.

jensw_2000 31. Mai 2013 05:23

AW: 1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern
 
Zitat:

Zitat von BUG (Beitrag 1217042)
Vielleicht besteht ja auch Interesse an Notifications. Viel cooler als Polling :mrgreen:
Aber keine Ahnung wie gut das funktioniert, habe keine praktische Erfahrung mit MSSQL.

Die Notifications funktionieren technisch ganz sicher, aber warum soll man sich in diesem Fall vom SQL Server benachrichtigen lassen das ein Datensatz geändert wurde, um dann auf dieses Event zu regieren und die Daten dann effektiv doch wieder zur Kontrolle von "lastUpdate" abzufragen? ... :gruebel:

Wir wissen doch, dass wir gerade mit ".Post" Daten geschrieben haben. Da muss uns doch kein Zweiter drüber informieren ..

Eventuell kann man den entgültigen "lastUpdate" Wert aber auch schon kontrollieren, nachdem das ADO Feld gefüllt wurde...
Delphi-Quellcode:
DSData.FieldbyName('lastupdate').AsDateTime := lastUpdate;
lastUpdate := DSData.FieldbyName('lastupdate').value;
Wäre einen Versuch wert. Dann spart er sich das "Read after Write".
Obwohl natütlich nichts über ein paar Zeilen guten alten SQL Code geht ..:wink:

Furtbichler 31. Mai 2013 07:08

AW: 1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern
 
Zitat:

Zitat von Piro (Beitrag 1217031)
Für mich ist die Sekunde wichtig, da ich das lastupdate aus der Anwendung in einer weiteren Abfrage verwende

Das ist der eigentliche Fehler. Es entspricht nicht dem Wesen eines Datums/Uhrzeitwertes, als Identifikator für einen Datensatz herzuhalten. Du kannst Klimmzüge unternehmen (runden z.B.), aber das ist imho einfach nicht richtig. Was ist, wenn plötzlich zwei Anwendungen gleichzeitig Daten generieren. Oder eine Anwendung innerhalb einer Sekunde mehrere Datensätze?

Du möchtest doch einen eindeutigen Identifikator, um deine Daten wiederzufinden, oder? Dann verwende einen.

Um einen Datensatz zu markieren, verwende wahlweise einen Zähler (identity), eine GUID (uniqueIdentifier) oder einen Timestamp.
Du kannst das clientseitig generieren, hast aber dann i.A. das Problem, das bei Mehrfachzugriff auf die Schreibfunktionen diese Identifikatoren u.U. nicht eindeutig ist (Ausnahme: GUID).

Mein Tipp: Verwende eine IDENTITY-Spalte. Genausogut geht aber eine GUID oder TimeStamp-Spalte. ADO liefert dir den neu erzeugten Wert, wenn Du die Feldinformation dieser Spalte richtig initialisierst (Eigenschaften 'AutoGenerateValue'). Auch wenn es immer wieder diesbezüglich Fragen gibt.

Eine Alternative wäre das Absetzen des Befehls 'INSERT' mit der 'OUTPUT'-Klausel, was ich wiederum sehr charmant finde:
SQL-Code:
insert
  YourTable
  (Fields)
output
  inserted.PKColumn
values
  (<YourValueList>)
also z.B.:
SQL-Code:
--Create Table MyTable (ID int IDENTITY (1,1), Name VarChar(50))
insert MyTable (Name) output inserted.ID values ('Furtbichler')
Diesen Befehl kannst Du in einer TADOQuery ausführen. Natürlich mit parametrierten Werten

jobo 31. Mai 2013 07:31

AW: 1 Sekunde Unterschied zwischen DB DateTime Feld und Anwendung beim Speichern
 
Fraglich ist außerdem, einen clientbasierten Zeitstempel einzutragen. Wie willst Du kontrollieren, wie die Clients ihre Uhrzeit eingestellt haben? Ich meine, da gehört ein Serverdatum hin. Das wiederum am besten per Trigger.
Und auch wenn Du dann an der Stelle sauber bist, solche Datumsabfragen gehören normal nicht in die Verarbeitung- wie bereits angeführt wurde, wenn dann ins Reporting.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:47 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz