AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Prism Fließkommazahlen Delphi vs. Oracle
Thema durchsuchen
Ansicht
Themen-Optionen

Fließkommazahlen Delphi vs. Oracle

Ein Thema von Raffigator · begonnen am 4. Jun 2007 · letzter Beitrag vom 4. Jun 2007
Antwort Antwort
Raffigator

Registriert seit: 5. Mär 2007
Ort: Wedel
46 Beiträge
 
Delphi 2006 Professional
 
#1

Fließkommazahlen Delphi vs. Oracle

  Alt 4. Jun 2007, 10:42
Datenbank: Oracle • Version: 10g • Zugriff über: Bdp
Hallo,
ich habe ein Problem mit dem Decimalseparator.
Ich möchte über eine Delphi-Anwendung Fließkommazahlen in einer Oracle-Datenbank speichern. Oracle erwartet einen '.' als Trennzeichen, während Delphi das ',' benutzt. Ich habe die NLS_NUMERIC_CHARACTERS umgestellt, so dass ein Speichern möglich ist. Die Zahlen werden auch richtig in der Datenbank abgelegt!
Lese ich nun aber mit meiner Anwendung die Tabelle wieder aus, wird das Trennzeichen einfach überlesen und ich habe anstatt 7.45 nun 745.
Kann mir jemand einen Tip geben, wie man am besten mit Fließkommazahlen umgeht?
Raphael
MfG
Raphael
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: Fließkommazahlen Delphi vs. Oracle

  Alt 4. Jun 2007, 10:57
Zitat von Raffigator:
Ich möchte über eine Delphi-Anwendung Fließkommazahlen in einer Oracle-Datenbank speichern. Oracle erwartet einen '.' als Trennzeichen, während Delphi das ',' benutzt.
Hi,
so ganz richtig ist das nicht. Eigentlich zeigt das aus schon, dass Du auf den National Language Support zurückgreifst. An sich benutzen sowohl Delphi als auch Oracle einfach lokalisierte Einstellungen. Delphi greift dabei immer auf die Einstellungen unter Windows zurück. I.d.R. wirst Du in Deutschland Rechner mit deutscher Lokalisierung finden und hier ist eben das Komma der Dezimalseperator. Wichtig ist, dass Du Dich eigentlich nie auf diesen verlassen solltest. Das man selbst einen solchen Rechner verwendet heißt natürlich nicht, dass alle Rechner auf denen das Programm einmal läuft ebenfalls diesen Dezimalseperator verwenden. So kann ein Kunde durchaus einen englisch lokalisierten haben, der erwartet dann den Dezimalpunkt (und natürlich kommen noch ganz andere Dinge in Frage).
Deshalb greift man häufig auf eine einheitliche Lokalisierung zurück, damit eine Datei auf einem dt. Rechner gespeichert und problemfrei auf einem eng. geladen werden kann und vice versa.

Dafür gibt es spezielle Strukturen, die Informationen über die bei einer Konvertierung zu verwendenden Einstellungen enthalten. Unter Delphi.Win32 währen das TFormatSettings, unter .net findest Du Implementierungen des IFormatProvider-Interface. In Deinem Fall die Klasse NumberFormatInfo und hier die Eigenschaft numberDecimalSeperator. Erzeuge hier eine neue Instanz, setz den Dezimalseperator und übergib diese Instanz dann an die toString Methode als zweites Argument (erstes ist weiterhin die zu konvertierende Zahl).

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Raffigator

Registriert seit: 5. Mär 2007
Ort: Wedel
46 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Fließkommazahlen Delphi vs. Oracle

  Alt 4. Jun 2007, 11:19
Hi,

danke erstmal für deine Antwort!
Problem ist, ich benutze keine toString-Methode. Ich lese die Datenbank aus und fülle den Inhalt in ein Datagrid bzw. DataSet und dort verschwindet das Komma dann einfach.
Beim Speichern habe ich das Problem, dass wenn ich die NLS-Einstellungen nicht vornehme jedesmal ein Fehler auftritt, wenn ich meinen Datenkomponenten einen Floatwert zuweise

Delphi-Quellcode:
      
with BdpUpdate2, Datensatz do begin
        if Connection.State = System.Data.ConnectionState.Closed then
          Connection.Open;

        Parameters.Item[0].Value := fConvertStrToDouble(VS,2);
        Parameters.Item[1].Value := U1ERST1;
        if U1SATZ1 <> 'then
          Parameters.Item[2].Value := fConvertStrToDouble(U1SATZ1,2);
        Parameters.Item[3].Value := U1ERST2;
        if U1SATZ2 <> 'then
          Parameters.Item[4].Value := fConvertStrToDouble(U1SATZ2,2);
        Parameters.Item[5].Value := U1ERST3;
        if U1SATZ3 <> 'then
          Parameters.Item[6].Value := fConvertStrToDouble(U1SATZ3,2);
        Parameters.Item[7].Value := U1ERST4;
        if U1SATZ4 <> 'then
          Parameters.Item[8].Value := fConvertStrToDouble(U1SATZ4,2);
        Parameters.Item[9].Value := U1ERST5;
...
end;
Wenn ich den Parametern beispielsweise einfach einen String zuweise wie 7.45, '7.45', oder aber auch 7,45, wird das nicht akzeptiert, da es nicht als Floatwert erkannt wird...
Raphael
MfG
Raphael
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: Fließkommazahlen Delphi vs. Oracle

  Alt 4. Jun 2007, 11:38
Zitat von Raffigator:
Problem ist, ich benutze keine toString-Methode.
Ok, Du verwendest die fConvertStrToDouble-Methode. Da ich gerade nichts zu der finde mal die Frage, wo kommt die denn her? Was macht die denn? Und falls die nur in meiner Hilfe fehlt, gibt es die überladen, so dass man hier wieder einen Dezimalseperator angeben könnte?

Zitat von Raffigator:
Beim Speichern habe ich das Problem, dass wenn ich die NLS-Einstellungen nicht vornehme jedesmal ein Fehler auftritt, wenn ich meinen Datenkomponenten einen Floatwert zuweise
Das ist klar. Das kannst Du halt wieder ändern, sobald Delphi automatisch den korrekten Dezimalseperator verwendet.
  Mit Zitat antworten Zitat
Raffigator

Registriert seit: 5. Mär 2007
Ort: Wedel
46 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Fließkommazahlen Delphi vs. Oracle

  Alt 4. Jun 2007, 11:48
Zitat von Der_Unwissende:
Ok, Du verwendest die fConvertStrToDouble-Methode. Da ich gerade nichts zu der finde mal die Frage, wo kommt die denn her? Was macht die denn? Und falls die nur in meiner Hilfe fehlt, gibt es die überladen, so dass man hier wieder einen Dezimalseperator angeben könnte?
Nein, die gibt es nicht überladen, da ich mir die Methode selber geschrieben habe. Ich paste sie mal hier rein

Delphi-Quellcode:
{_______________________________________________________________________________
Wandelt einen String in eine Floatzahl um

  @param Fstring (in)    : String, der umgewandelt werden soll
  @param decimals (in)  : Anzahl der Nachkommastellen

  @return (out)          : 0    --> Zahl konnte nicht umgewandelt werden
                            sonst --> umgewandelte Float-Zahl
_______________________________________________________________________________}

function fConvertStrToDouble(Fstring : string ; decimals : integer):double;
var
  i : byte;
  temp : double;
  settings : TFormatSettings;
begin
  Result := 0;
  kommaCount := 0;
  
 //englischen Zahlen-Standard laden (Decimalseperator = '.')
  GetLocaleFormatSettings(1033, settings);
  for i := 1 to Length(Fstring) do
    if Fstring[i] = ',then begin
       fString[i] := '.';
    end;

 
  //String umwandeln
  if TryStrToFloat(Fstring,temp,settings) then
    Result := temp;
end;
Beschreibe nochmal kurz, was ich überhaupt machen will. Also ich lese eine Txt-Datei ein, in der Datensätze gespeichert sind. Es geht halt darum diese Datensätze nun in der Datenbank zu speichern. In der Txt-Datei sind die Fließkommazahlen mit einem ',' gespeichert.
Ich lese also die Zahl mit dem Komma als String ein und will es dann in der fConvertStrToDouble umwandeln. Wie du siehst habe ich da auch schonmal mit den TFormatSettings gearbeitet. (Ist das überhaupt .Net-Kompatibel?)
Wie gesagt, bisher sind bei mir alle Versuche mit dem Komma als Separator zu arbeiten, fehlgeschlagen.
Raphael
MfG
Raphael
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#6

Re: Fließkommazahlen Delphi vs. Oracle

  Alt 4. Jun 2007, 12:04
Warum musst du überhaupt umwandeln? DAS ist der große Fehler.
Dem Oracle client ist es schnurz-piepe was die Regionaleinstellungen des Users im Betriebssystems sind.
Steht in der Registry AMERICA_AMERICAN, dann wird er das nehmen.
Du hast also in deiner Anwendung keine große Möglichkeit anhand der Windowseinstellungen auf die Oracle einstellungen zu schließen. [1]

Aber jetzt kommt der Punkt: Warum auch?
Eine Number(10,4) kann in in einer DataColumn mit ähnlicher Formatierung abgebildet werden.
SQL Statements sollten natürlich immer mit vernünftig typisierten Parametern erfolgen.
Somit sollte es für dich niemals das Problem geben, dass du in deinem Code einen Dezimalwert als String benutzen willst.
Die einzige Stelle wo das passiert ist in dem Control an das die Daten gebunden wurden.
Stört dich aber im Code nicht weiter, weil es jede Eingabe verhindert, die nicht in den Zieltypen umgewandelt werden kann.

Wie du bereits gemerkt hast, stellt das Datagrid nur die Dinge da, die du ihm als Datenquelle vorgibst, gib ihm einfach die richtigen Spaltentypen und alles ist in Butter...

[1] Nicht lange darüber wundern: Oracle hat neben extrem komplexen und ähm coolen Features, soviele mittelalterliche und hirnrissige Macken und/oder Implementierungslücken, es würde Monate dauern die alle aufzulisten...
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#7

Re: Fließkommazahlen Delphi vs. Oracle

  Alt 4. Jun 2007, 12:04
Zitat von Raffigator:
In der Txt-Datei sind die Fließkommazahlen mit einem ',' gespeichert.
Ich lese also die Zahl mit dem Komma als String ein und will es dann in der fConvertStrToDouble umwandeln. Wie du siehst habe ich da auch schonmal mit den TFormatSettings gearbeitet. (Ist das überhaupt .Net-Kompatibel?)
Wie gesagt, bisher sind bei mir alle Versuche mit dem Komma als Separator zu arbeiten, fehlgeschlagen.
Ok, nochmal, Du liest Die Daten aus einer txt-Datei? Wenn diese dort mit einem Komma als Seperator stehen, solltest Du auf jeden Fall die Umwandlung immer mit einem Komma als Dezimalseperator vornehmen. Ich dachte eigentlich, dass Du die Werte eben als Strings in eine SQL-Anfrage steckst und Oracle dann damit seine Probleme hat. Die Übergabe von umgewandelten Zahlen sollte hingegen kein Problem sein, da sich hier die Anbindung der DB um die korrekte Umwandlung kümmern müsste. Wenn Du allerdings dort Deinen Fehler hast (hab ich dann nur falsch verstanden), dann fällt mir auch nichts ein.
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#8

Re: Fließkommazahlen Delphi vs. Oracle

  Alt 4. Jun 2007, 12:12
Zitat von Der_Unwissende:
Ok, nochmal, Du liest Die Daten aus einer txt-Datei? Wenn diese dort mit einem Komma als Seperator stehen, solltest Du auf jeden Fall die Umwandlung immer mit einem Komma als Dezimalseperator vornehmen. Ich dachte eigentlich, dass Du die Werte eben als Strings in eine SQL-Anfrage steckst und Oracle dann damit seine Probleme hat. Die Übergabe von umgewandelten Zahlen sollte hingegen kein Problem sein, da sich hier die Anbindung der DB um die korrekte Umwandlung kümmern müsste. Wenn Du allerdings dort Deinen Fehler hast (hab ich dann nur falsch verstanden), dann fällt mir auch nichts ein.
D'oh! Das habe ich gar nicht gesehen...

btw: In dem Moment, in dem man sich dazu entschließt externe Dateien zu nehmen, ist man immer auch verplichtet sicherzustellen, dass die Werte auch wieder ausgelesen werden können.
Hmpf?
Nun, wenn ich mit deutschen Regionaleinstellungen eine Zahl in einen Text umwandel, erhalte ich "2,34", im englischen "2.34".
Du musst also Standards vorgeben wie das zu passieren hat, oder bestehende standas benutzen. XML wäre hierfür natürlich ideal, aber selbst eine CSV-Datei ist nicht komplett witzlos, wenn man sich an die CSV-Standards hält (also nicht so wie Excel zum Bleispiel).
Wenn dir die etwas komischen XMLs ausreichen, die ein DataSet auspsuckt, dann hast du das Speichern/Lesen von/zu XML schon eingebaut.
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Raffigator

Registriert seit: 5. Mär 2007
Ort: Wedel
46 Beiträge
 
Delphi 2006 Professional
 
#9

Re: Fließkommazahlen Delphi vs. Oracle

  Alt 4. Jun 2007, 12:35
Zitat von Der_Unwissende:
Ich dachte eigentlich, dass Du die Werte eben als Strings in eine SQL-Anfrage steckst und Oracle dann damit seine Probleme hat. Die Übergabe von umgewandelten Zahlen sollte hingegen kein Problem sein, da sich hier die Anbindung der DB um die korrekte Umwandlung kümmern müsste.
Wo genau das Problem liegt, weiß ich eben selber nicht so genau. Da ich jedoch eine ORA-Fehlermeldung zurückbekomme, gehe ich mal davon aus, dass Oracle das Problem ist.
Also ich benutze die Borland Data Provider und dort weise ich ja jedem Parameter seinen Wert zu (wie oben im kleinen Code-Schnipsel zu sehen).
Angenommen ich wandle meinen eingelesenen String garnicht um, bekomme ich eine Fehlermeldung, dass es keine gueltige Zahl ist. Selbst wenn ich einem Parameter einen konkreten Doublewert zuweise, bekomme ich diese Fehlermeldung! Sobald ich wie gesagt meine NLS_NUMERIC_CHARACTERS in Delphi setzte, bekomme ich keinen Fehler mehr (das lässt mich wiederum daran zweifeln, dass es ein ORACLE-Problem ist!?)


Zitat von Elvis:
Nun, wenn ich mit deutschen Regionaleinstellungen eine Zahl in einen Text umwandel, erhalte ich "2,34", im englischen "2.34".
Du musst also Standards vorgeben wie das zu passieren hat, oder bestehende standas benutzen. XML wäre hierfür natürlich ideal, aber selbst eine CSV-Datei ist nicht komplett witzlos, wenn man sich an die CSV-Standards hält (also nicht so wie Excel zum Bleispiel).
Wenn dir die etwas komischen XMLs ausreichen, die ein DataSet auspsuckt, dann hast du das Speichern/Lesen von/zu XML schon eingebaut.
Ich will die Datei nur auslesen und die Datensätze in der Datenbank speichern! Ist dies einmal geschehen, ist die Datei überflüssig und kann gelöscht werden. (altes COBOL-System soll durch neues DB-System ersetzt werden).


Das ganze kann doch nicht so kompliziert sein? Ich bin doch sicher nicht der erste, der Float-Werte in einer Datenbank speichern will!???
Raphael
MfG
Raphael
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#10

Re: Fließkommazahlen Delphi vs. Oracle

  Alt 4. Jun 2007, 13:03
Zitat von Raffigator:
Das ganze kann doch nicht so kompliziert sein? Ich bin doch sicher nicht der erste, der Float-Werte in einer Datenbank speichern will!???
Ist es auch nicht.Du hast auch schon mehrfach gehört wo das Problem ist und wie du es lösen kannst.
Es gab allerdings keine explizite Punkt-für-Punkt Anleitung.
Aber um etwas genauer zu werden: Wenn du die Datei einliest kannst du mit Integer.Parse einen String in eine Zahl umwandeln.
Besonders beachten solltest du den Overload, der einen IFormatProvide bekommt.

Hier mal etwas Pseudo code:
Delphi-Quellcode:
var
  deinNumberFormat : NumberFormatInfo;
begin
  // Clone, weil wir ja nicht das Format für die ganze Anwendung verändern wollen!
  deinNumberFormat := CultureInfo.Create('de').NumberFormat.Clone() as NumberFormat;
  deinNumberFormat.Blabla // ändere die Eigenschaften, die du anders als in "de" brauchst
...
  einDecimal := Decimal.Parse('2,2', deinNumberFormat);
Natürlich willst du nicht ständig ein neues FormatInfo anlegen, aber das ist reine Implementierung und somit deine Sache.
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Antwort Antwort


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 11:26 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