mf
Goto Top

SQL 2005 Server - Werden Daten falsch ausgelesen?

Hi zusammen.

Wenn ich im SQL Management Studio des SQL2005-Servers eine Datentabelle abfrage, erhalte ich ein entsprechendes Ergebnis für ein spezielles Feld.

Das Ergebnis ist 500. bzw es wird als 500.0000000000000 ( ganze viele nullen ) angezeigt.

Das Feld ist vom Type "decimal(38,20)".

Wenn ich die Datenbank-Tabelle remote abrufe, in einem PHP-Script, so erhalte ich für einige Datensätze ein Ergebnis von 499.999999999 .. was ja nicht unbedingt 500 entspricht.

Nun ist meine Frage woran das liegen kann. Denn wenn ich mit dem ManagementStudio den Select absetze, scheint ja alles zu klappen.

Ich habe versuche mit "*1" das Problem zu lösen. Dies funktioniert auch soweit, aber wenn ich Felder mit der Anzeige habe/hatte, welche vorher 5000.00000000001 angezeigt haben, werden diese dann auch 4999.99999 (etc) angezeigt.

Hat einer eine Idee, um das Phänomen in den Griff zu bekommen?

Thx
Markus

Content-ID: 101576

Url: https://administrator.de/contentid/101576

Ausgedruckt am: 20.11.2024 um 08:11 Uhr

filippg
filippg 11.11.2008 um 22:49:56 Uhr
Goto Top
Hallo,

man merke: Das Binärformat ist nicht zur Darstellung von Nachkommastellen im Dezimalsystem geeignet face-wink.
In sofern: benötigst du wirklich diesen Datentyp? Manchmal kann man sich auch behelfen, indem man Wert*1000 (o.ä.) speichert, d.h. den Wert auf Ganzzahlen normiert.

Gruß

Filipp
mf
mf 11.11.2008 um 23:07:32 Uhr
Goto Top
Hi Filipp.

Leider habe ich keinen Einfluss auf das Design der Datenbank. Dies ist ein gekauftes Produkt, welches aktuell auch unter dem Dach von Microsoft befindet.

Ich versuche lediglich Daten auszulesen, habe dafür extra einen ReadOnly-SQL-Account angelegt. Allerdings habe ich o.g. Problem.

Nachkommastellen benötige ich aber auf jeden Fall.

Der bisherige Trick "*1" klappt scheinbar nicht überall. Was die Ursache dafür ist, weiss ich nicht.

Ich versuche mal *1000/1000. Mal sehen, ob's was bringt.

Gruss
Markus
Netzheimer
Netzheimer 12.11.2008 um 07:33:13 Uhr
Goto Top
Das Problem bei decimal (auch numeric) ist, dass beim Berechnen Gesamtstellen (bei dir 38) und Nachkommastellen alleine (20) Berücksichtigt werden. In diesem Fall wären maximal 18 Stellen vor dem Komma und 20 Stellen danach. Das wird auch bei Berechnungen so berücksichtigt.

Kannst du sagen, warum du so eine Genauigkeit brauchst oder wäre auch float möglich?
mf
mf 12.11.2008 um 13:15:00 Uhr
Goto Top
"ich" brauche die Anzahl der Nachkommastellen nicht. Die Benutzer würden evtl mit vier Nachkommastellen auskommen.

Aber ... das System ist unantastbar. face-wink

D.h. ich muss einen Weg finden, der mit dieser obstrusen Beschaffenheit der Datenbank klar kommt.

Wenn du schreibst, dass nur gewissen Stellen in die Berechnung einfliesen .. Ist es möglich auch nur geziehlte eine bestimmte Anzahl an Stellen anzufragen?

ála .. SELECT nachkommas(Spaltenname,4) FROM tabelle

Wenn es eine Funktion gibt, die sowas machen kann, wäre das evtl schon eine Lösung. Bin leider in MSSql nicht so fit.

Thx
Markus
Biber
Biber 12.11.2008 um 13:40:00 Uhr
Goto Top
Moin mf,

du kannst in diesem Fall vermutlich nur durch Probieren dem Ziel näher kommen.
Der M$-Server stellt vermeintlich "vergleichbare" Funktionen unter SSIS/TransAct-SQL bereit, die allerdings mal "runden", mal abschneiden..

In Frage kommen zum einen CAST/CONVERT-Funktionen, zum anderen die ROUND()-Funktion, nach der Du gefragt hast.

Zum Ziel führen sollte am ehesten
SELECT ROUND( deineSpalte, 4) as feldname from deineTabelle;
-- oder--
SELECT 1.0* ROUND( deineSpalte, 4) as feldname from deineTabelle;

Wobei zu prüfen bleibt, ob das Ergebnis identisch ist, wenn Du
  • mit der ROUND()-Funktion einen passenden View zusammentrümmerst (also die Logik im View hinterlegst)
  • die Round()-Funktion innerhalb eines dynamisch erzeugten Statements verwendest.

Laut MSDN ist das Ergebnis von Round() zwar immer -je nach Sichtweise- "richtig", aber eben unterschiedlich.
Redmonder Logik halt...

Grüße
Biber
mf
mf 12.11.2008 um 14:00:26 Uhr
Goto Top
Danke für deine Unterstützung.

Beide Vorschläge bzgl ROUND() funktionieren leider nicht.

ROUND(..., 4) liefert das gleiche "falsche" Ergebnis, mit mehr als 4 Nachkommastellen.
1* ROUND(..., 4) liefert das gleiche Ergebnis, als wenn ich auch nur " *1 " anfüge.

CAST/CONVERT hattest du noch angesprochen. Könntest Du hier noch ein kleines Beispiel posten?

"Netzheimer (Daniel)" schreibt, dass "float" evtl auch ausreichen könnte.

Wie kann ich die Spalte mit CAST/CONVERT umformen?

Thx
Markus

ps. Ich verwende keine Views ... (die Datenbank ist unantastbar. face-wink)
mf
mf 12.11.2008 um 14:15:32 Uhr
Goto Top
Hi Biber

Danke für den Denkanstoß CAST/CONVERT.

Mit unser aller Freund goo.... konnte ich eine Lösung finden.

CONVERT(decimal(38,10), spaltenmame) alias

Damit werden die amüsanten Daten nun korrigiert anzeigt, ohne eine Änderung an der Datenbank.

Thx
Markus
Biber
Biber 12.11.2008 um 14:18:15 Uhr
Goto Top
Moin mf,

hmm, das "falsche ROUND()-Ergebnis mit mehr als 4 NK-Stellen" verstehe ich nicht...
Kannst Du mal Test-Query und Output posten bitte?

Beispiel zu CAST:

SELECT CAST( datFeld  as decimal(18, 4)) as feldname 
From DeineTabelle

Grüße
Biber
[Edit] Uuups, das war über Kreuz....
kannst Du trotzdem bitte noch das falsche Round()--Ergebnis posten... rein interessehalber?
[/Edit]
mf
mf 12.11.2008 um 16:21:05 Uhr
Goto Top
kannst Du trotzdem bitte noch das falsche Round()--Ergebnis posten... rein interessehalber?

Der Query ist wie bisher geblieben .. halt um das ROUND() ergänzt, aus Deinem Post.

Das Ergebnis war wie im ersten Post gewesen. Also 499.9999 (ganz viele 9er)

Einen Screen aus dem ManagementStudio könnte ich dir zwar posten, aber dort ist es ja erstaunlicherweise korrekt in der Anzeige.

Gruss
Markus