Benutzer mit den meisten Antworten
Uhrzeit, wo keine hingehört

Frage
-
Hallo zusammen,
hin und wieder taucht in einer von mir entwickelten Anwendung ein sehr merkwürdiges Phänomen mit fatalen Folgen auf. In mehreren zusammen hängenden SPs werden Daten auf der Basis von Datumswerten bearbeitet. Die Berechnungen sind recht komplex und im Einzelnen hier nicht von Belang. Wichtig ist, dass in der Datenbank normalerweise nur Datumswerte ohne Uhrzeiten gespeichert werden und alle Berechnungen nur auf Datumsebene (in Form von z.B. DATEDIFF(d, Datum1, Datum2) und DATEADD(d, 1, Datum)) erfolgen. Uhrzeiten werden bei diesen Berechnungen nirgendwo gebraucht.
Die Änderungen an den Datensätzen werden in einer eigenen Tabelle geloggt, so dass ich im Bilde bin, welche Änderungen stattfinden. In dieser Tabelle gibt es u.a. Felder für "AltesDatum", "NeuesDatum" und für einen Timestamp, an dem die Änderung in die DB geschrieben wurde. Wie aus dem Nichts tauchen zuweilen in den dann auch in der DB gespeicherten SP-Variablen Uhrzeiten auf, die im Feld "NeuesDatum" gespeichert werden. Die Uhrzeit liegt immer etwas vor der Uhrzeit, die im Timestamp-Feld gespeichert wird.
Im Laufe des Tages taucht genau diese Uhrzeit in ganz anderen Datensätzen ebenfalls auf, die mit denen, in denen der Fehler ursprünglich aufgetreten ist, nichts weiter zu tun haben als häufig den gleichen Benutzer, der die erste Transaktion einst angestoßen hat. Zwischen dem ersten Fehler und den nächsten können z.T. Stunden liegen. Das Datum, das mit der Uhrzeit zusammen gespeichert wird, kann ein völlig anderes sein.
Mir kommt es so vor, als ob diese "Geisteruhrzeiten" irgendwo im Speicher des Servers herumschwirren und sich an Datumswerte hängen, die zufällig in diesen Speicherbereich geschrieben werden. Ist so etwas denkbar?
Für jeden Hinweis bin ich dankbar.
Viele Grüße,
Michael Schörner
Antworten
-
Hallo zusammen,
es scheint, Gott sei Dank, keine "vagabundierenden" Uhrzeiten im SQL Server zu geben - nur nachlässige Programmierer. Ich habe eine Stelle in einer SP gefunden, bei der tatsächlich eine Uhrzeit unter ganz bestimmten Bedingungen in eine Variable hätte gelangen können. Das Loch ist mittlerweile gefixt.
Allen, die sich mit mir zusammen den Kopf zerbrochen haben, möchte ich danken.
Viele Grüße,
Michael Schörner- Als Antwort markiert Michael Schörner Montag, 15. Oktober 2012 11:55
Alle Antworten
-
Hallo Michael,
"Geisteruhrzeiten" könnte es allerhöchstens geben, wenn deine Datenbank hinüber ist. Aber aufgrund deiner Schilderung mag ich daran nicht wirklich glauben.
Es wäre wahrscheinlich sinnvoller, sich zu fragen, wer und/oder was ändert/speichert diese Werte. Von alleine kommen die nicht da rein. Ich denke eher, dass eine SP falsch programmiert ist oder dass von anderer Stelle aus schreibend auf die Datenbank zugegriffen und dabei dann keine Rücksicht auf deine Vorgaben bzgl. Uhrzeit genommen wird.
Ich persönlich würde - zumindest zeitweise - eine vollständige Protokollierung sämtlicher Änderungen vornehmen. Das geht bspw. mit entsprechenden Triggern auf jede Tabelle, die die geänderten Daten in eine Protokolltabelle schreiben. Alternativ schau dir mal das hier an:
http://msdn.microsoft.com/de-de/library/cc280424.aspx
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort vorgeschlagen Stefan FalzModerator Dienstag, 16. Oktober 2012 18:34
-
-
Hallo Olaf,
falls der SQL Server (und der [virtuelle] Windows Server, auf dem dieser läuft) keine Uhrzeiten aus dem Nichts schöpft, bleibt nur die Möglichkeit, dass die Uhrzeit vom Clientprogramm (Access-ADE) generiert wird. Ich bin jeglichen Code mehrfach durchgegangen, ohne eine Stelle zu finden, an der das passieren könnte. Zumal die Uhrzeit "vererbt" wird, d.h. an Daten ganz anderer Datensätze zu ganz anderen Zeiten angehängt wird.
Beispiele aus dem Transaktionslog:
ID Termin Rücknahmedatum Verfügbardatum NeuesVerfügbardatum Timestamp
------------------------------------------------------------------------------------------------------------------------------------------------------------------
7109 57159 2012-10-09 00:00:00.000 2012-10-10 00:00:00.000 2012-10-19 09:25:29.320 2012-10-08 09:25:33.523 (hier erscheint die Uhrzeit erstmalig)
7124 56938 2012-10-11 00:00:00.000 2012-10-18 00:00:00.000 2012-10-16 09:25:29.320 2012-10-08 12:16:12.513
7143 56732 2012-10-04 00:00:00.000 2012-10-18 00:00:00.000 2012-10-16 09:25:29.320 2012-10-08 16:14:18.943Weder die aufrufende Clientfunktion noch die SPs im SQL Server speichern diese Daten irgendwo zwischen. Ich könnte ja noch verstehen, wenn ein Fehler immer neue Uhrzeiten generiert, aber dass er die gleiche immer wieder recyclet, bleibt mir ein Rätsel?
Diese Funktionen werden täglich zigmal ausgeführt und laufen zu 98% problemlos. Neben der Spur lassen sich hier keine Daten ins System bringen. Der Benutzer stößt den Prozess nur an, der dann automatisch abläuft. Auffällig ist, dass der Fehler in den meisten Fällen morgens zwischen acht und zehn Uhr auftritt und in den meisten Fällen nur bei ganz bestimmten Benutzern. Die Abweichung der Uhrzeit von "NeuesVerfügbardatum" und "Timestamp" resultiert wahrscheinlich daher, dass die Uhrzeit zu Beginn der Transaktion erzeugt wird, während der Timstamp gesetzt wird, wenn die geänderten Daten in die DB zurückgeschrieben werden. Die ganze Transaktion ist recht komplex und dauert eine zeitlang.
Gruß,
Michael -
Am 09.10.2012 09:36, schrieb Michael Schörner:> Hallo Olaf,>> falls der SQL Server (und der [virtuelle] Windows Server, auf dem dieser> läuft) keine Uhrzeiten aus dem Nichts schöpft, bleibt nur die> Möglichkeit, dass die Uhrzeit vom Clientprogramm (Access-ADE) generiert> wird. Ich bin jeglichen Code mehrfach durchgegangen, ohne eine Stelle zu> finden, an der das passieren könnte. Zumal die Uhrzeit "vererbt" wird,> d.h. an Daten ganz anderer Datensätze zu ganz anderen Zeiten angehängt wird.>> Beispiele aus dem Transaktionslog:>> ID Termin Rücknahmedatum Verfügbardatum> NeuesVerfügbardatum Timestamp> ------------------------------------------------------------------------------------------------------------------------------------------------------------------> 7109 57159 2012-10-09 00:00:00.000 2012-10-10 00:00:00.000> 2012-10-19 09:25:29.320 2012-10-08 09:25:33.523 (hier erscheint die> Uhrzeit erstmalig)Bin auch überzeugt, daß die Daten irgendwo geschrieben werden.Wird im Access evtl irgendwo mit Now() anstatt Date() gearbeitet?Obwohl ich bisher davon überzeugt war, daß Access keine Tausendstelkennt - was dafür spricht, daß der Wert aus dem SQL-Server kommt.Prüfe Stellen an denen du mit GETDATE() arbeitest.Prüfe ob DEFAULT-Werte in den Tabellen eingestellt sind.Prüfe ob es Trigger gibt, die vielleicht Datumswerte setzen.Wie machst du eigentlich dein Logging?Evtl kannst du dort auch speichern, welcher Nutzer von welchem Host etcden Datensatz ändert.Lutz
- Als Antwort vorgeschlagen Stefan FalzModerator Dienstag, 16. Oktober 2012 18:35
-
Hallo Lutz,
in den SPs wird GETDATE() and zwei Stellen verwendet, um einen Grenzwert zu bestimmen (SET @grenzwert = DATEADD(d, 2, GETDATE())). Alle Operationen mit diesem Wert laufen dann über DATEDIFF(d, @grenzwert, @datum). Ein "Überspringen" der Uhrzeit im Grenzwert sollte unmöglich sein, da der Grenzwert nie einer anderen Variable zugeordnet wird, mit der weitergerechnet wird.
Um diese unmögliche Möglichkeit gänzlich auszuschließen, habe ich nun vor der Zuweisung der Grenzvariablen noch eine Funktion geschaltet, die den Uhrzeitanteil entfernt. Mal schauen, was dabei heraus kommt.
Gruß,
Michael -
Hallo Michael,
GETDATE() liefert, anders der Name es vermuten lassen würde, die Uhrzeit mit.
SELECT DATEADD(d, 2, GETDATE())
liefert also bspw. das hier:2012-10-11 16:44:18.840
Was Du nun aber mit Grenzwert überspringen, ... meinst, weiß ich nicht.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Stefan,
dass GETDATE() die Uhrzeit mitliefert, weiß ich. Deshalb entferne ich ja nun auch die Uhrzeit, bevor ich das Datum der Variablen zuweise, die den Grenzwert hält.
Mit "Überspringen" meine ich, das "Wandern" der Uhrzeit aus einer Variablen in eine andere, ohne dass es zu einer expliziten Zuweisung kommt. Ich weiß, dass das unmöglich ist (jedenfalls, wenn alles so funktioniert, wie es soll).
Ich warte jetzt erst einmal ab, ob der Fehler wieder einmal auftaucht, und forsche dann weiter. Leider kann es sein, dass es Wochen dauert, bis der Fehler erneut auftritt.
Gruß,
Michael -
Imho liegt es genau da. Denn dein Datenmodell scheint ja DATETIME-Angaben in der Form ohne Zeitanteil zu benötigen. Das ist für mich ein Business Constraint der durch die Datenbank, mittels Trigger in diesem Fall, durchgesetzt werden muss. Alternativ geht auch ein CHECK Constraint.
USE tempdb; CREATE TABLE Test ( ID INT IDENTITY , dt DATETIME NOT NULL CHECK ( dt = DATEADD(DAY, 0, DATEDIFF(DAY, 0, dt)) ) ); go PRINT 'Good'; INSERT INTO Test ( dt ) VALUES ( '20121001' ); go PRINT 'Bad'; INSERT INTO Test ( dt ) VALUES ( GETDATE() ); go PRINT 'Result'; SELECT * FROM Test; go DROP TABLE Test; go
-
Hallo zusammen,
es scheint, Gott sei Dank, keine "vagabundierenden" Uhrzeiten im SQL Server zu geben - nur nachlässige Programmierer. Ich habe eine Stelle in einer SP gefunden, bei der tatsächlich eine Uhrzeit unter ganz bestimmten Bedingungen in eine Variable hätte gelangen können. Das Loch ist mittlerweile gefixt.
Allen, die sich mit mir zusammen den Kopf zerbrochen haben, möchte ich danken.
Viele Grüße,
Michael Schörner- Als Antwort markiert Michael Schörner Montag, 15. Oktober 2012 11:55
-
Hallo Michael,
prima, dass es nun funktioniert. Es wäre für andere, die evtl. mal dasselbe Problem haben aber sinnvoll, wenn Du die Postings, die auf den Fehler - der sich ja nun bewahrheitet hat - hinweisen, als Antwort markieren würdest.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community