AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten
Thema durchsuchen
Ansicht
Themen-Optionen

TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

Ein Thema von cltom · begonnen am 30. Apr 2022 · letzter Beitrag vom 2. Mai 2022
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.750 Beiträge
 
Delphi 12 Athens
 
#1

AW: TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

  Alt 30. Apr 2022, 15:59
Bei leerem Edit.Text wird qry.FieldByName('Nummer').AsString := Edit.Text eher als Leerstring in der DB landen als als Null.
Zumindest bei einem TIntegerField wird es das eben nicht. Dort wird in SetAsString explizit ein Clear aufgerufen wenn der String leer ist. Das setzt allerdings voraus, dass in der Datenbank auch wirklich ein Integer Feld steht und kein String Feld. Aber das entnehme ich auch so der bisherigen Beschreibung.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
cltom

Registriert seit: 22. Sep 2005
230 Beiträge
 
Delphi 12 Athens
 
#2

AW: TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

  Alt 30. Apr 2022, 16:39
Als DB-Schnittstelle kommt aktuell (noch) ZeosDB zum Einsatz, künftig vermutlich FireDAC (Update auf 11.1 steht auch ins Haus, dabei gleich mit FireDAC). Als zusätzlich Komplikation: aktuell wird noch in eine lokale SQLite geschrieben, bald mal auf einen SQL-Server.

Datensensitive Controls hab ich lange überlegt, dann aber nicht verwendet ... allen voran wohl weil ich nicht abschätzen konnte, wie aufwändig das werden würde, wenn ich viele der Felder für diverse Rechnungen brauche oder sich einige der Felder auch erst aus Berechnungen ergeben. Kann man sicher lösen, aber ich hatte mich nicht drüber getraut. Aktuell repräsentieren meine Objekte recht schön den realen Anwendungsfall.

Betreffend Nullable Types: ist es am Ende nicht genau das Szenario, dass man zu jeder Variable ein bool mitführt, das sagt, ob die Variable gesetzt wurde? Dann muss man beim Schreiben also den Status dieses Bools abfragen und dann entscheiden, ob man die Variable in den SQL Befehl aufnimmt. Nicht nur, dass man muss sie im Grunde auch mit in die SQL schreiben, um sicher zu gehen, dass beim Lesen aus der DB nicht erst recht wieder ein 0 als Ergebnis in die Variable kommt.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.587 Beiträge
 
Delphi 7 Professional
 
#3

AW: TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

  Alt 30. Apr 2022, 16:44
Bei leerem Edit.Text wird qry.FieldByName('Nummer').AsString := Edit.Text eher als Leerstring in der DB landen als als Null.
Zumindest bei einem TIntegerField wird es das eben nicht. Dort wird in SetAsString explizit ein Clear aufgerufen wenn der String leer ist. Das setzt allerdings voraus, dass in der Datenbank auch wirklich ein Integer Feld steht und kein String Feld. Aber das entnehme ich auch so der bisherigen Beschreibung.
Du hast recht, bei 'nem Stringfeld in der DB wird qry.FieldByName('Nummer').AsString := Edit.Text eher als Leerstring in der DB landen als als Null.
Aber bei nummerischen Feldern in der DB ist dort ja letztlich auch kein Leersting in der DB möglich, also muss da "irgendwas anderes für das Feld passendes" gefunden werden. Und das ist bei Integer ... halt leider nicht Null sondern 0. Und damit sind wir dann bei unserem Ursprungsproblem.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.750 Beiträge
 
Delphi 12 Athens
 
#4

AW: TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

  Alt 30. Apr 2022, 17:03
Aber bei nummerischen Feldern in der DB ist dort ja letztlich auch kein Leersting in der DB möglich, also muss da "irgendwas anderes für das Feld passendes" gefunden werden. Und das ist bei Integer ... halt leider nicht Null sondern 0.
Diese Aussage wage ich zu bezweifeln. Auch ein Integer-Feld in der Datenbank kann natürlich NULL sein. Es ist allerdings so, dass TIntegerField über AsInteger oder Value in dem Fall 0 liefert. Was soll es auch anders tun, wenn ein Integer abgefragt wird. Deswegen hatte ich ja auch auf AsString für das Schreiben und Lesen hingewiesen. Das liefert nämlich bei NULL wieder einen Leerstring und nicht '0'.

Das Problem ist also nicht die DB oder das TEdit, auch nicht Zeos, FireDAC oder TIntegerField. Wenn das nicht funktioniert liegt der Fehler woanders.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.587 Beiträge
 
Delphi 7 Professional
 
#5

AW: TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

  Alt 30. Apr 2022, 17:18
Das Integer in der DB Null sein kann ist klar, aber dazu muss dann die Schnittstelle auch Null liefern und nicht aus 'nem leeren String eine 0 machen.

Also ein Versuch:

Ein Leerstring per .AsString in ein nummerisches Feld der Datenbank, führt nicht zwingend zu einem Null in der Datenbank sondern (vermutlich) eher zu einer 0.

Ein Leerstring per .AsString in ein Stringfeld der Datenbank, führt nicht zwingend zu einem Null in der Datenbank sondern (vermutlich) eher zu einem Leerstring.

Null bekommt man eher per .AsVariant := EmptyParam in die Datenbank, dabei sollte der Feldtyp nicht von Belang sein.

So besser oder hab' ich was übersehen, unklar formuliert, ...? Bin mir da halt nicht so wirklich sicher.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.750 Beiträge
 
Delphi 12 Athens
 
#6

AW: TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

  Alt 30. Apr 2022, 22:08
Ein Leerstring per .AsString in ein nummerisches Feld der Datenbank, führt nicht zwingend zu einem Null in der Datenbank sondern (vermutlich) eher zu einer 0.
Vermutlich? Ich kann dir versichern, dass es nicht so ist - bestätigt durch Lesen der Sourcen und Ausprobieren. Kannst du gerne selbst prüfen.

Ein Leerstring per .AsString in ein Stringfeld der Datenbank, führt nicht zwingend zu einem Null in der Datenbank sondern (vermutlich) eher zu einem Leerstring.
Zumindest bei Verwendung von FireDAC kann man das über ein Property der Connection steuern: TFDFormatOptions.StrsEmpty2Null
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.587 Beiträge
 
Delphi 7 Professional
 
#7

AW: TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

  Alt 1. Mai 2022, 09:37
Ein Leerstring per .AsString in ein nummerisches Feld der Datenbank, führt nicht zwingend zu einem Null in der Datenbank sondern (vermutlich) eher zu einer 0.
Vermutlich? Ich kann dir versichern, dass es nicht so ist - bestätigt durch Lesen der Sourcen und Ausprobieren. Kannst du gerne selbst prüfen.

Ein Leerstring per .AsString in ein Stringfeld der Datenbank, führt nicht zwingend zu einem Null in der Datenbank sondern (vermutlich) eher zu einem Leerstring.
Zumindest bei Verwendung von FireDAC kann man das über ein Property der Connection steuern: TFDFormatOptions.StrsEmpty2Null
Da wir hier von ZeosDB reden, und es dort datenbankabhängig (leicht) unterschiedliche Implementierungen gibt, kann ich halt (pauschal leider) nicht mit absoluter Sicherheit sagen, welches Verhalten zu erwarten ist.

Und da ich kein XE2 habe und auch keine Sourcen dazu, kann ich nicht im Quellcode nachschauen und mit Sicherheit sagen, wie das Verhalten dort genau sein kann, soll, darf oder muss.

Bei meinem Delphi werden per ADO Integer bzw. Float per .AsString := '' zu Null, ein VarChar wird mit .AsString := '' zu einem Leerstring.

Ist das so ein klar definiertes Verhalten, das bei allen Dantenbankkomponenten zu erwarten ist?
Dann sollte das im Eingangspost beschriebene Problem mit der grundsätzlichen Nutzung von .AsString := Edit.Text bei Integer- bzw. Floatwerten zu lösen sein.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.750 Beiträge
 
Delphi 12 Athens
 
#8

AW: TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

  Alt 1. Mai 2022, 22:59
Ist das so ein klar definiertes Verhalten, das bei allen Dantenbankkomponenten zu erwarten ist?
Das das Verhalten bereits von TIntegerField in Data.DB implementiert wird, müsste eine andere Zugriffsschicht schon eine eigene TIntegerField-Komponente mitbringen, die das dann auch noch anders (und somit inkompatibel) löst.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Frickler

Registriert seit: 6. Mär 2007
Ort: Osnabrück
634 Beiträge
 
Delphi XE6 Enterprise
 
#9

AW: TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

  Alt 2. Mai 2022, 08:38
Mach Dir nen eigenen Datentyp, ein record oder eine Klasse mit dem eigentlichen Wert und einem Flag "gesetzt" und die passenden Methoden dabei, u.a. ein Setter und ein "WriteToField(ds: TDataSet; const fn: string)", bei dem Du dann je nach "gesetzt" entweder den Wert übergibst oder das Feld unverändert lässt oder auch löschst.
Statt "TryStrToFloat" musst Du dann sowas wie "try StrToFloat... gesetzt := true; except .. end" nutzen. Vielleicht gleich als Methode mit in den eigenen Datentyp packen.
  Mit Zitat antworten Zitat
cltom

Registriert seit: 22. Sep 2005
230 Beiträge
 
Delphi 12 Athens
 
#10

AW: TryStrToFloat/TryStrToInt, leeren String nicht als 0 erhalten

  Alt 2. Mai 2022, 08:50
Mach Dir nen eigenen Datentyp, ein record oder eine Klasse mit dem eigentlichen Wert und einem Flag "gesetzt" und die passenden Methoden dabei, u.a. ein Setter und ein "WriteToField(ds: TDataSet; const fn: string)", bei dem Du dann je nach "gesetzt" entweder den Wert übergibst oder das Feld unverändert lässt oder auch löschst.
Statt "TryStrToFloat" musst Du dann sowas wie "try StrToFloat... gesetzt := true; except .. end" nutzen. Vielleicht gleich als Methode mit in den eigenen Datentyp packen.
den Teil kann ich mir noch gut vorstellen, aufwändig, aber denkbar, aber dann die SQL-Befehle basteln. Da muss man dann bei jedem einzelnen Wert erst mal prüfen, ob das Flag gesetzt ist. Da erscheint es fast leichter, das Flag einfach mitzuschreiben in die SQL, weil dann der SQL-string im Grunde unverändert bleibt. Es wird alles geschrieben (Null oder nicht), aber eben auch das Flag wird geschrieben, sodass ich beim lesen das wieder gesetzt hab.

oder seh ich das falsch an Deinem Ansatz? sonst ist die Idee ja schön mit dem Record, weil man das Verhalten dann auch standardisieren kann
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz