Einzelnen Beitrag anzeigen

gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#1

Rundungsproblem mit MSSQL

  Alt 8. Apr 2021, 15:56
Datenbank: MSSQL • Version: 2017 • Zugriff über: ADO
Hallo Delphi-Gemeinde,

ich haben einen komischen Effekt mit dem MSSQL-2017 im Delphi Rio (Win32/VCL-Anwendung) (WIN-10).
Ich möchte aus einer Rechnung die Summe aller Netto-Beträge, multipliziert mit deren Steuersatz als Brutto-Betrag ermitteln.
Aber irgendwie bekomme ich komische, falsch gerundete Beträge zurück.

Hier ein SQL der das Problem verdeutlichen soll:
Code:
Select
      sum (l.[Preis]) as Netto_Org
,    round(sum ([Preis]),2) as Netto_Round
,    206.5 * 1.19 as Brutto_Korrekt
,    round(206.5 * 1.19,2) as Brutto_Korrekt_round
,    sum( l.[Preis] * ( (r.steuersatz +100) / 100)) as Brutto_Org
,    sum( round(l.[Preis],2) * ( (r.steuersatz +100) / 100)) as Brutto_1
,    round(sum( round(l.[Preis],2) * ( (r.steuersatz +100) / 100)),2) as Brutto_2
,    round( sum( l.[Preis] * ( (r.steuersatz +100) / 100)),2) as Brutto_3
,    round( sum( l.[Preis] * 1.19) ,2) as Brutto_4
,    sum( round( l.[Preis] * 1.19 ,2)) as Brutto_5
,    sum( round( l.[Preis],2) * 1.19 ) as Brutto_6

from RechnungListe l, Rechnung r
where ....
group by r.steuersatz;
also Ergebnis dieser Query bekomme ich:
Code:
Netto_Org  Netto_Round Brutto_Korrekt Brutto_Korrekt_round Brutto_Org Brutto_1    Brutto_2    Brutto_3    Brutto_4    Brutto_5    Brutto_6
----------- ----------- -------------- -------------------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
206,5       206,5       245,735        245,74               245,735     245,735     245,73      245,73      245,73      245,72      245,735
Alle Einzelpositionen (l.[Preis]) sind floats und mit 2 Nachkommastellen gespeichert.
Der Netto-Betrag dieser Rechnung ist tatsächlich 206.50 (€), der Steuersatz ist 19 (%).
Schaut man sich aber [Brutto_1], [Brutto_2] oder [Brutto_3] an, stimmen die Rundung nicht. [Brutto_4], [Brutto_5] und [Brutto_6] sind Versuche mögliche Fehler auszuschließen.

Und jetzt wird's richtig wild.
Fetsche ich den [Netto_Org]-Wert heraus (im Debugger = 206.5) und schreibe den Wert in eine extended-Variable, multipliziere mit 1.19 erhalte ich wieder 245.735
Runde ich anschließen die Variable mit RoundTo (Wert,-2) bekomme ich 245.73 heraus, statt 245.74.

Delphi-Quellcode:
var
  nPow, nValue : extended;
begin
  nPow := power(10,2);

// Test 1
  nValue := ADO.FieldByName('Netto_org').AsFloat; // 206.5 laut Debugger
  nValue := nValue * 1.19;
  nValue := RoundTo(nValue,-2);
// = 245.73 , falsch

// Test 2
  nValue := ADO.FieldByName('Netto_org').AsFloat; // 206.5 laut Debugger
  nValue := nValue * 1.19;
  nValue := nValue * nPow;
  nValue := nValue + 0.5;
  nValue := trunc(nValue); // <- hier passiert etwas komisches !! 24574 wird zu 24573 ???
  nValue := nValue/nPow;
// = 245.73 , falsch

// Test 3
  nValue := 206.5;
  nValue := nValue * 1.19;
  nValue := RoundTo(nValue,-2);
// = 245.74 , korrekt.

// Test 4
  nValue := ADO.FieldByName('Netto_round').AsFloat; // ebenfalls 206.5 laut Debugger
  nValue := nValue * 1.19;
  nValue := RoundTo(nValue,-2);
// = 245.74 , korrekt.
Irgendwie bekomme ich von der Datenbank nicht den korrekten Wert zurück, bzw. die Rundung im SQL-Server funktioniert nicht richtig.
Kann mir jemand erklären was hier schief läuft?

Danke.
  Mit Zitat antworten Zitat