![]() |
AW: MS SQL Genauigkeit in der Termauswertung
Ja, so erhalte ich das erwartete Ergebnis. Wir haben eine Tabelle mit Formeln, die vom SQL Server ausgewertet werden + ich bin sehr sehr sicher, dass das früher anders funktioniert hat. Der 2008R2 ist schon Jahre im Einsatz + das Problem ist jetzt erst aufgepoppt.
Wir werden wohl in allen Formeln die Skalare mit .0 ergänzen. :-( |
AW: MS SQL Genauigkeit in der Termauswertung
keine Ahnung ob diese Beobachtung nun so ist wie sie ist, aber wenn, dann:
Mal bei MS nachschlagen, solche Änderungen werden eigentlich nicht "einfach so" mal ins Feld geworfen. Es müsste dazu Migrationshinweise geben und normalerweise auch Schalter, die das (alte) Verhalten bewahren, forcieren usw. Kommt natürlich bei der Art der Anpassung auf das zu erwartende Änderungesvolumen an und wie exakt man die Problemstellung überhaupt finden kann. |
AW: MS SQL Genauigkeit in der Termauswertung
Hallo,
hm, also hier ![]() steht The precision and scale of the numeric data types besides decimal are fixed. If an arithmetic operator has two expressions of the same type, the result has the same data type with the precision and scale defined for that type. Und weiter unten ist noch eine Tabelle. Das war also schon immer so, zumindestens beim 2012-er |
AW: MS SQL Genauigkeit in der Termauswertung
Vielleicht ist das bei uns auch einfach durchgerutscht und die Erinnerung siegt über Tatsachen. Oder - wie es so schön heisst: Die Wahrheit ist eine Tochter der Zeit.
Das Problem gibt es wahrscheinlich auch nur, wenn man das SQL Statement als Text zusammenbaut, sonst hat man eh Paramter und passende Datentypen. Aber zum Merken: <int> <op> <int> liefert <int>. |
AW: MS SQL Genauigkeit in der Termauswertung
Delphi und ADO:
SQL-Code:
FlameRobin
select 12/100*0.5 from dual; => 0
select 0.5/100*12 from dual; => 0 select 0.1*(12/100*0.5) from dual; => 0 select 0.1*(0.5/100*12) from dual; => 0 select (12/100)*0.5 from dual; => 0 select (0.5/100)*12 from dual; => 0 select 0.1*(12/100)*0.5 from dual; => 0 select 0.1*(0.5/100)*12 from dual; => 0
SQL-Code:
select 12/100*0.5 from dual; => 0,0
select 0.5/100*12 from dual; => 0,0 select 0.1*(12/100*0.5) from dual; => 0,00 select 0.1*(0.5/100*12) from dual; => 0,00 select (12/100)*0.5 from dual; => 0,0 select (0.5/100)*12 from dual; => 0,0 select 0.1*(12/100)*0.5 from dual; => 0,00 select 0.1*(0.5/100)*12 from dual; => 0,00 Zitat:
Zwei Nachkommastellen * zwei Nachkommastellen = 4 Nachkommastellen. ![]() Ok, wenn man sich das Ergebnis über FlameRobin anschaut, so stimmt das, die Regel wird eingehalten. Über Delphi und ADO werden die Nachkommastellen (bei Beachtung der Regel) jedoch nur ausgegeben, wenn sie <> 0 sind. Taschenrechner & Co. scheinen da etwas "flexibler" zu sein, sie erweitern die Nachkommastellen implizit, wenn es für eine korrekte Darstellung des Ergebnisses erforderlich scheint. Fazit: Rechnen über Select nur, wenn man sich der Einhaltung dieser Regel bewusst ist. |
AW: MS SQL Genauigkeit in der Termauswertung
Du machst die Sache kompliziert, denn hier geht es um MS-SQL Server. DUAL gibt es für den nicht und wie ich beschrieben habe, sind die Ergebnisse andere:
select 12/100*0.5 --> 0 select 0.5/100*12 --> 0,06 |
AW: MS SQL Genauigkeit in der Termauswertung
Von einer nicht ganz kleinen DB bin ich es gewohnt,daß ich für jeden numerischen Wert das gewünschte Ausgabeformat definiert habe. Und das hat ganz gut funktioniert.
Mit irgendwelchen Seiteneffekten zu rechnen ohne daß mich jemand für meine Genialität feiert war mir auf Dauer zu anstrengend. Gruß K-H |
AW: MS SQL Genauigkeit in der Termauswertung
Verstehe ich nicht. Was meinst du damit?
|
AW: MS SQL Genauigkeit in der Termauswertung
Zitat:
Und warum das in DIESEM Fall durchaus interessant ist: Das Ergebnis der Rechnung wäre 0,006 (3 Nachkommastellen), wenn nun aber in der Rechnung (0.1 * (0.5 / 100 * 12)) nur 2 Nachkommastellen vorkommen und daher davon ausgegangen wird, das man nur 2 Nachkommastellen braucht ist das Ergebnis logischerweise Falsch! Folglich müsste man generell mit der maximal möglichen Anzahl an Kommastellen rechnen um einigermaßen vernünftig rechnen zu können (und keine Angst haben muss, das dadurch Kommastellen schlichtweg gestrichen werden). Daher: 0.1 * (0.5 / 100 * 12) = 0.00 0.1 * (0.50 / 100 * 12) = 0.006 (?) @Tigerlilly: Zitat:
select (12/100)*0.5 --> ? select 12/100*0.50 --> ? |
AW: MS SQL Genauigkeit in der Termauswertung
Nur damit wir alle auf dem gleichen Stand sind
SQL-Code:
ergibt auf dem MS SQL 2017 ausgeführt
select 1,12/100*0.5
union select 2,0.5/100*12 union select 3,0.1*(12/100*0.5) union select 4,0.1*(0.5/100*12) union select 5,0.1*12/100*0.5 union select 6,0.1*0.5/100*12
Code:
1 - 0
2 - 0.06 3 - 0 4 - 0.006 5 - 0.006 6 - 0.006 ![]() Warum also jetzt der Unterschied zwischen Zeile 3 und Zeile 5? Ganz einfach: Es wird in Zeile 3 erst der Wert in den Klammern berechnet, und der ergibt (wie man in Zeile 1 sehen kann) eben 0 und diese 0 mit 0.1 multipliziert ergibt weiterhin 0. Das ist das ganze Geheimnis PS Der wirkliche Problemauslöser ist die Division von zwei Ganzzahlen 12/100. Es würde reichen eine davon als Fließkommazahl zu deklarieren. Also 12/100.0 oder 12.0/100. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:21 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 by Thomas Breitkreuz