Anmelden

View Full Version : SQL, eringefallen wegen nachkomma stellen



Seiten : [1] 2

dibe
07-11-23, 16:15
Hallo zusammen

ich errechne in einem SQL die Mwst

nicht als "* 1,19" sondern

sum(feld) +((sum(feld)/100)*MWSTFELD)

Feld ist 7,2
MWSTFELD ist 5,2

In meinem Fehler habe ich einen Satz, mit dem FELD : 8,70

Ich reche 8,70 + 8,70/100*19 = 10,35
Sql errechnet 10,22
Intern ist für SQL 8,7/100 nur 0,08
auch ein DEC(sum(feld)+((sum(feld)/100)*mwstfeld), 7, 2)
ändert das nicht.

Kann ich irgendwie, am besten Global, das interne unnützue abschneiden abstellen damit er mit 0,087 weiterrechnet ?
Da ist ja jeder dumme Taschenrechner richtiger!

Vielen Dank
Dietlinde Beck

B.Hauser
07-11-23, 18:35
Wenn du eine konstante Zahl ohne Nachkomma-Stellen angibst wird diese als Integer-Wert interpretiert.
Die Regeln bei Integer-Werten sind etwas anders:
1. Werden 2 Integer-Werte miteinander verrechnet ist das Ergebnis wieder ein Integer-Wert, also 95/100 ergibt rein rechnerisch 0,95, da aber bei Integer-Werten irgendwelche Nachkommastellen abgeschnitten werden und da an dieser Stelle nicht gerundet wurde, ist das Ergebnis 0.
2. Die Anzahl der Nachkommastellen wird bei der Rechnung mit Integer-Werten nicht erhöht. Deshalb kommt auch bei 8,7/100 nur 0,08 heraus.
Die einfachste Lösung ist, wenn Du anstatt 100 100,0 angibtst. 100,0 wird als Fließkomma interpretiert und das ganze Problem mit dem "falschen" Rechnen entfällt.


Values(8,70 + 8,70/100,0*19); --> ergibt: 10,35300000000000000000000000000

Alternativ kannst Du natürlich auch 100 explizit auf Dezimal casten.


Values(8,70 + 8,70*19/Cast(100 as Dec(3, 0))); --> ergibt ebenfalls das richtige Ergebnis

dibe
08-11-23, 07:50
Hallo Frau Hauser, vielen Dank!


...das ganze Problem mit dem "falschen" Rechnen entfällt.

Wenn ein Taschenrechner auch diese "klugheit" hätte, würder ich "falschen" ja verstehen.
So empfinde ich es als sehr unglückliche Lösung, die auf jeder einfachen SQL Schulung genannt werden sollte.
Es ist einfach unüblich, bei einer Berechnung extra zu erwähnen, das man es "richtig" haben möchte.
Obwohl ..... im RPG habe ich mich an EVAL(RH) als grundsätzlichen Rechenbefehl gewöhnt.

Danke für die schnelle Hilfe.
Dietlinde Beck

Fuerchau
08-11-23, 08:18
Ich verwende häufiger statt "/ 100" eher "* 0,01";-).
Damit ist das Ergebnis dann dezimal mit 4 Nachkomma.

Die Integerarithmetik schlägt nur zu, wenn alle Operanden Integer oder Ganzzahlen sind.
Wenn ich also "dec(8.70, 11, 2) / 100" schreibe erhalte ich auch 0,087 mit 22 Dezimalen.

dibe
08-11-23, 09:00
Na ja, das besonders ärgerliche ist ja, das der 'übliche' Test im interaktiven SQL,

Select 8,7/100 from Datei

0,0870000000 bringt

Da kommt doch keiner drauf, das das im SQLRPGLE PGM dann nur noch 0,08 ist

dibe
08-11-23, 09:14
Korrektur:
/100,00 oder /100.00 kann SQL gar nicht! (interaktiv)

sum(feld1)+((sum(feld1)/100,00)*Feld2)
mit feld1 = 8,70 und feld2 = 19,00
und der definition Feld1 = 7,2 bzw Feld2 5,2
ergibt 8,70

auch
/Cast(100 as Dec(3, 0)) ergibt 8,70 !!!
auch mit 100.00 kommt 8,70 heraus



mit *0,01 ist das ergebnis OK

Fehler oder Feature?

Danke Herr Fuerchau
Dietlinde Beck

camouflage
08-11-23, 10:16
Ich hab mir halt angewöhnt bei solchen Operationen die Division am Schluss zu machen oder Felder mit genügend Kommastellen. Hast Du das auch ausprobiert?
sum(feld) +((sum(feld)*MWSTFELD)/100)

Andreas_Prouza
08-11-23, 10:27
Na ja, das besonders ärgerliche ist ja, das der 'übliche' Test im interaktiven SQL,

Select 8,7/100 from Datei

0,0870000000 bringt

Da kommt doch keiner drauf, das das im SQLRPGLE PGM dann nur noch 0,08 ist

Wie sieht denn dein Code aus?
Ich hab jetzt mal schnell ein Beisipel gemacht und hab das erwartete Ergebnis im RPG bekommen.:

dcl-s l_1 packed(5 : 3);

exec sql set :l_1 = 8.7 / 100;

dsply (%char(l_1));


Ergebnis: DSPLY .087

Oder hab ich was falsch verstanden?

dibe
08-11-23, 10:41
@carmuflage
Das geht auch.
Wiederspricht aber irgendwie der Aussage von Frau Hauser, das die 100 anstatt einer 100,00 schuld ist.

@Herr Prouza
Es ist ein

insert into Datei
select sum(...

in einem SQLRPGLE Pgm, nicht *FREE V7R5 alle PTF

Die Felder in der Zieldatei sind alle mit 2 NK-Stellen.

Fazit:
Division als letztes (Carmuflage) geht,
*0,01 anstatt /100 (Fuerchau) geht auch
/100 rechnet (Ich), aber das ergebnis ist abgeschnitten (0,08 statt 0,087)
/100,00 oder /100.00 oder /Cast(100 as Dec(3, 0)) (Frau Hauser) rechnet nicht, Ergebnis 8,70

Für meine Kollegen und mich nicht wirklich logisch!

Danke an alle
Dietlinde Beck

camouflage
08-11-23, 11:01
Doch Dietlinde,
das ist durchaus logisch. Wenn Du ein Feld mit 7.2 definierst, werden halt die übrigen Dezimalstellen abgeschnitten. Siehe Beispiel Andreas, welcher die dritte Stelle erhalten hat. Daher, Dezimal genügend gross oder Division am Schluss.