Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Problem mit Devart MyDac (https://www.delphipraxis.net/202491-problem-mit-devart-mydac.html)

juelin 10. Nov 2019 11:48

Datenbank: MySql • Version: MariaDB • Zugriff über: MyDac

Problem mit Devart MyDac
 
Hallo Gemeinde,

Delphi 10.3 Community Edition.
Windows 10
Devart MyDac 10.0.1
Datenbank MySql MariaDB

bin am verzweifeln.
Die Procedure hat immer funktioniert und jetzt nicht mehr.
Will ein Feld (Systole) in der Tabelle vital ändern.
Geht aber nicht.

Delphi-Quellcode:
          Form1.MyCommand1.SQL.Clear;
          Form1.MyCommand1.SQL.Add('UPDATE vital SET Systole=:Sys WHERE Nachname=:Nac AND Vorname=:Vor AND Geburtsdatum=:Geb AND Datum=:Dat AND Uhrzeit>=:Uhr1 AND Uhrzeit<=:Uhr2');
          Form1.MyCommand1.ParamByName('Sys').Name:='Sys';
          Form1.MyCommand1.ParamByName('Sys').DataType:=ftInteger;
          Form1.MyCommand1.ParamByName('Sys').Value:=e3sys;
          Form1.MyCommand1.ParamByName('Nac').Name:='Nac';
          Form1.MyCommand1.ParamByName('Nac').DataType:=ftString;
          Form1.MyCommand1.ParamByName('Nac').Value:=e3nn;
          Form1.MyCommand1.ParamByName('Vor').Name:='Vor';
          Form1.MyCommand1.ParamByName('Vor').DataType:=ftString;
          Form1.MyCommand1.ParamByName('Vor').Value:=e3vn;
          Form1.MyCommand1.ParamByName('Geb').Name:='Geb';
          Form1.MyCommand1.ParamByName('Geb').DataType:=ftDateTime;
          Form1.MyCommand1.ParamByName('Geb').Value:=e3geb;
          Form1.MyCommand1.ParamByName('Dat').Name:='Dat';
          Form1.MyCommand1.ParamByName('Dat').DataType:=ftDateTime;
          Form1.MyCommand1.ParamByName('Dat').Value:=e3dat;
          Form1.MyCommand1.ParamByName('Uhr1').Name:='Uhr1';
          Form1.MyCommand1.ParamByName('Uhr1').DataType:=ftDateTime;
          Form1.MyCommand1.ParamByName('Uhr1').Value:=h8;
          Form1.MyCommand1.ParamByName('Uhr2').Name:='Uhr2';
          Form1.MyCommand1.ParamByName('Uhr2').DataType:=ftDateTime;
          Form1.MyCommand1.ParamByName('Uhr2').Value:=h9;
          Form1.MyCommand1.Execute;
          if SqlRet then
          begin
SqlRet ist der Rückgabewert (Result) aus TForm1.MyCommand1AfterExecute(Sender: TObject; Result: Boolean);
SqlRet ist TRUE

Der Wert Systole in Datenbank ist vorher und nachher 135.
Wert e3sys (im Parameter sys) ist aber 137
Alle anderen Paramerterwerte sind in Ordnung.
Nach Execute ist der Wert Systole in Datenbank immer noch 135.

Hat jemand eine Idee was das ist?
Oder wie man das testen kann?

Danke und Gruß
Jürgen

blawen 10. Nov 2019 12:36

AW: Problem mit Devart MyDac
 
Wird der Datensatz wirklich gefunden oder existieren mehrere, welche auf die Bedingung zutreffen?
Als kritisch sehe ich hier die Uhrzeit!

Code:
UPDATE vital SET Systole=:Sys WHERE Nachname=:Nac AND Vorname=:Vor AND Geburtsdatum=:Geb AND Datum=:Dat AND Uhrzeit>=:Uhr1 AND Uhrzeit<=:Uhr2
Generell würde ich den Zeitraum so angeben
Code:
DATUM BETWEEN :Datum_Start AND :Datum_Ende

juelin 10. Nov 2019 12:51

AW: Problem mit Devart MyDac
 
es gibt nur einen Datensatz mit Datum = 2.1.2000 und Uhrzeit = 14:00:00
Datum in e3dat ist 2.1.2000
Uhrzeit in Uhr1 = 14:00:00 und Uhr2 = 14:00.59

juelin 10. Nov 2019 12:58

AW: Problem mit Devart MyDac
 
Problem ist die Ujrzeit.
Wenn ich die Uhrzeit in der WHERE-Klause weglasse, so funktioniert der Update.
Das geht aber nur weil es zu dem Datum nur einen Satz in der Datenbank gibt.
Was ist wenn es mehrere Datensatze zu einem Datum gibt?

hoika 10. Nov 2019 13:02

AW: Problem mit Devart MyDac
 
Hallo,
mach mal aus dem Update- einen Select-Befehl

Select * From vital WHERE Nachname=:Nac AND Vorname=:Vor AND Geburtsdatum=:Geb AND Datum=:Dat AND Uhrzeit>=:Uhr1 AND Uhrzeit<=:Uhr2');

scrat1979 10. Nov 2019 13:08

AW: Problem mit Devart MyDac
 
Ich habe mit AbsoluteDatabase in meinem Terminplaner ein ähnliches Phänomen was letztendlich mit einem Rundungsfehler von TDateTime (Uhrzeit ist ja die nachkommestelle) zusammenhängt. Damit schlägt zum Beispiel der Vergleich „14:00:00“ aus der Datenbank = „14:00:00“ über EncodeDatetime fehl. Habe ewig gebraucht um den Fehler zu finden. Ich berechne mir nun in einer eigenen Funktion (über EncodeDateTime und YearOf, MinuteOf etc.) den TDateTime-Wert neu und vergleiche dann den berechneten Wert. Somit ist der „Rundungsfehler“ identisch und der Vergleich gelingt. Performance-Einbußen im merklichen Bereich habe ich bei ca. 3000 Datensätzen, welche so in einem Wisch neu berechnet werden, nicht.

Ob dir dies weiterhelfen wird weiß ich nicht, aber ich wollte dir meine Erfahrung nicht vorenthalten.

Neumann 10. Nov 2019 13:22

AW: Problem mit Devart MyDac
 
Würde Uhr1 mal auf 13:59 setzten, geht das?

juelin 10. Nov 2019 13:38

AW: Problem mit Devart MyDac
 
Hallo scrat1979
ich glaube Du hast recht.
Aber irgendwie funktioniert es nicht bei mir.
Habe mit EncodeTime gearbeitet.
Kannst Du mir mal ein Beispiel senden.
Danke und Gruß
Jürgen

scrat1979 10. Nov 2019 14:18

AW: Problem mit Devart MyDac
 
Zitat:

Zitat von juelin (Beitrag 1451106)
Hallo scrat1979
ich glaube Du hast recht.
Aber irgendwie funktioniert es nicht bei mir.
Habe mit EncodeTime gearbeitet.
Kannst Du mir mal ein Beispiel senden.
Danke und Gruß
Jürgen

Aber natürlich :-)

Hier ist meine "Workaraound"-Funktion:

Delphi-Quellcode:
function RecodeDateTimeEx(ADateTime : TDateTime) : TDateTime;
begin
  Result := EncodeDateTime(YearOf(ADateTime), MonthOf(ADateTime), DayOf(ADateTime), HourOf(ADateTime), MinuteOf(ADateTime), SecondOf(ADateTime), 0); // ms spielen bei mir keine Rolle
end;
Folgendermaßen verwende ich die Funktion:

Delphi-Quellcode:
[...]
if FQuery.FieldByName('FeldName').AsDateTime = ZeitStempelZumVergleich then ... // Funktioniert nicht, obwohl Datum und Uhrzeit auch im Debugger identisch sind (wegen besagtem Umrechungsfehler)
if (RecodeDateTimeEx(FQuery.FieldByName('FeldName').AsDateTime) = RecodeDateTimeEx(ZeitStempelZumVergleich)) then ... // Funktioniert
[...]
Achte bitte noch darauf: Falls Du nur Uhrzeiten speicherst, aber ein Datum auch verwendet wird, vergisst nicht, dass Du Dir natürlich den Zeitstempel zuerst zusammenbauen musst:

Delphi-Quellcode:
Zeitstempel = DateOf(Datum) + TimeOf(Datum)
Eventuell vergleichst Du nämlich einen Zeitstempel mit Datum und Uhrzeit mit einem Zeitstempel, welcher Nur die Uhrzeit beinhaltet. Da schlägt der Vergleich Zeistempel1 = Zeitstempel2 natürlich auch fehl, da sich das Datum unterscheidet! Hier wäre es mal interessant zu wissen, wie die Zeitstempel im Debugger beim Vergleich aussehen. Über die "Falle" des unterschiedlichen Datums beim VErgleich bin ich nämlich auch schon gestolpert...


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:19 Uhr.

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