Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi [SQL] Ganzzahl ändern in Dezimalzahl mit 2 Nachkommstellen (https://www.delphipraxis.net/96177-%5Bsql%5D-ganzzahl-aendern-dezimalzahl-mit-2-nachkommstellen.html)

juergen 19. Jul 2007 20:50

Datenbank: Pervasive SQL • Version: 9.x • Zugriff über: ODBC

[SQL] Ganzzahl ändern in Dezimalzahl mit 2 Nachkommstellen
 
Hallo zusammen,

hänge schon länger an einem Problem, wo ich einfach nicht weiterkomme...

Habe folgende SQL-Anweisung:
SQL-Code:
SELECT (RIGHT(KtoRechWerte.Datum, 2) + '.' + SUBSTRING(KtoRechWerte.Datum, 5, 2) + '.' + LEFT(KtoRechWerte.Datum, 4)) , LTRIM(Personalstamm.PersNr),
Round((KtoRechWerte.Wert/60),2) FROM...
Entscheidend ist die Round((KtoRechWerte.Wert/60),2)-Bedingung.
Im Round() kommt -je nach Ergebnis- entweder eine Ganzzahl (z.B. -8) raus, oder eben eine Decimalzahl mit 2 Nachkommastellen.
Das Round() benötige ich unbedingt...Dieses DB-Feld ist ein Integertyp.
Jetzt habe ich einiges probiert mit Format, Decimal...
Bekomme aber immer eine Meldung, dass die SQL-Anweisung ungültig ist.

Hat hierzu jemand eine Idee?

Schon mal Danke vorab!

mkinzler 19. Jul 2007 20:54

Re: [SQL] Ganzahl ändern in Dezimalzahl mit 2 Nachkommstelle
 
Versuchs mal mit einem Cast:
SQL-Code:
SELECT
   ..., cast(Round((KtoRechWerte.Wert/60),2) as numeric(15,2)) FROM...

juergen 19. Jul 2007 21:16

Re: [SQL] Ganzahl ändern in Dezimalzahl mit 2 Nachkommstelle
 
Hallo mkinzler,
danke für den Tip!
Habe mir nun das Cast in Kombination mit as numeric angelesen, laut Beschreibung müsste das so passen...
Aber das Ergebnis ändert sich leider nicht. (es kommt auch kein SQL-Fehler)
Ich habe immer noch die Zahlen mit keiner oder nur einer Nachkommastelle... :cry:

mkinzler 19. Jul 2007 21:29

Re: [SQL] Ganzahl ändern in Dezimalzahl mit 2 Nachkommstelle
 
Nimm mal 3 als 2. Parameter des Round

juergen 19. Jul 2007 22:11

Re: [SQL] Ganzahl ändern in Dezimalzahl mit 2 Nachkommstelle
 
So sieht es aus mit "2" als 2. Parameter für Round():
19.07.2007;10;0
19.07.2007;10;3,5
19.07.2007;10;-20,5
19.07.2007;10;-100,5
19.07.2007;10;-592,88
19.07.2007;11;0
19.07.2007;11;-8
19.07.2007;11;-32
19.07.2007;11;-112
19.07.2007;11;-581,85
19.07.2007;96387;0
19.07.2007;96387;-8
19.07.2007;96387;-32
19.07.2007;96387;-112
19.07.2007;96387;-608

und so mit einer auf 3 Stellen zu rundenden Zahl:
19.07.2007;10;0
19.07.2007;10;3,5
19.07.2007;10;-20,5
19.07.2007;10;-100,5
19.07.2007;10;-592,883
19.07.2007;11;0
19.07.2007;11;-8
19.07.2007;11;-32
19.07.2007;11;-112
19.07.2007;11;-581,85
19.07.2007;96387;0
19.07.2007;96387;-8
19.07.2007;96387;-32
19.07.2007;96387;-112
19.07.2007;96387;-608

Ohne Verwendung von Round() sieht es so aus:
19.07.2007;10;3
19.07.2007;10;-20
19.07.2007;10;-100
19.07.2007;10;-592
19.07.2007;11;0
19.07.2007;11;-8
19.07.2007;11;-32
19.07.2007;11;-112
19.07.2007;11;-581
19.07.2007;96387;0
19.07.2007;96387;-8
19.07.2007;96387;-32
19.07.2007;96387;-112
19.07.2007;96387;-608

Es wird also alles als Ganzzahl erstellt, anscheinend wegen dem Tabellen-Feld-Typ "Integer"?

Wenn ich den 2.Parameter von Nummeric veränder, ändert sich nichts...

Ich müsste jetzt "nur" eine Verkettung hinbekommen nach dem Motto:
SQL-Code:
...((KtoRechWerte.Wert/60), + '(DecimalSeparator)' + Mod((KtoRechWerte.Wert),60))...
Wobei nun bei MOD auch ein Minuszeichen mit herauskommt...

mkinzler 19. Jul 2007 22:16

Re: [SQL] Ganzahl ändern in Dezimalzahl mit 2 Nachkommstelle
 
Und wenn du innerhalb des Round castest?
SQL-Code:
Round((cast(KtoRechWerte.Wert as numeric(15,2))/60),2)

juergen 19. Jul 2007 22:24

Re: [SQL] Ganzahl ändern in Dezimalzahl mit 2 Nachkommstelle
 
also das geht leider auch nicht.
Gerundet wird aber richtig.
Das heisst der Rückgabewert wird auch von Round als Zahl erkannt.
Nur warum funktioniert dann das Casten nicht?
Es kommt kein Fehler, zeigt aber auch keinerlei Wirkung, man könnte es genauso gut weg lassen und hätte dasselbe Ergebnis. :gruebel:

Hansa 19. Jul 2007 22:53

Re: [SQL] Ganzzahl ändern in Dezimalzahl mit 2 Nachkommstell
 
In der DB (eventuell gehts nur so) :

SQL-Code:
DECLARE EXTERNAL FUNCTION DIV
    INTEGER,
    INTEGER
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'IB_UDF_div' MODULE_NAME 'IB_UDF'
Auf Client Seite dann so :

Delphi-Quellcode:
function LeseRealFeld (d : TpFIBDataSet;FeldName : string) : real;
begin
  if StrVorhanden (FeldName) then
    LeseRealFeld := d.FieldByName(FeldName).AsCurrency
  else
    LeseRealFeld := 0;  // eventuell NULL
end;

mkinzler 20. Jul 2007 06:37

Re: [SQL] Ganzzahl ändern in Dezimalzahl mit 2 Nachkommstell
 
@hansa: Ich glaube kaum das IB/FB-UDFs bei Pervasive SQL (Nachfolger von BTRIEVE) funktionieren.

marabu 20. Jul 2007 08:11

Re: [SQL] Ganzzahl ändern in Dezimalzahl mit 2 Nachkommstell
 
Hi folks,

ich würde es so machen:

SQL-Code:
select cast(round(cast(k.wert as float) / 60, 2) as numeric(10, 2)) as wert
from ktorechwerte k, ....
Wichtig ist der innere Aufruf von CAST().

Freundliche Grüße

juergen 20. Jul 2007 18:55

Re: [SQL] Ganzzahl ändern in Dezimalzahl mit 2 Nachkommstell
 
Hallo zusammen,
so, habe einiges versucht Convert(xxx, SQL_Float), casten in allen Varianten, Decimal....
nichts geht.
Ich komme an marabus Vorschlag einfach nicht vorbei, denn dieser funktioniert! :thumb: Vielen Dank!
(ich frag mich nur, wie man da von selbst drauf kommen soll. :stupid: )
Wenn man sich in dem Referenz-Handbuch von der Datenbank durchwühlt, findet man mindesten 10 Varianten, wo man meinen könnte, dass das funktionieren sollte.
Naja, das ist wohl das Los von einem Anfänger.

Das nachfolgende verstehe ich auch überhaupt nicht...
Zitat:

Zitat von marabu
SQL-Code:
..as wert...

Was ist "wert"?
Ich habe jetzt:
SQL-Code:
SELECT (RIGHT(KtoRechWerte.Datum, 2) + '.' + SUBSTRING(KtoRechWerte.Datum, 5, 2) + '.' + LEFT(KtoRechWerte.Datum, 4)) , LTRIM(Personalstamm.PersNr), cast(round(cast(KtoRechWerte.Wert as float) /60, 2) as numeric(10, 2)) as Wert FROM KtoRechWerte, Personalstamm WHERE (KtoRechWerte.PersId = Personalstamm.Identifikation) AND...
Grüße aus Dortmund
Jürgen

DeddyH 20. Jul 2007 19:36

Re: [SQL] Ganzzahl ändern in Dezimalzahl mit 2 Nachkommstell
 
Zitat:

Zitat von juergen
Was ist "wert"?

Das ist lediglich ein Alias für das berechnete Feld, damit es einen sprechenden Namen bekommt und somit bequem ansprechbar ist.

marabu 20. Jul 2007 20:00

Re: [SQL] Ganzzahl ändern in Dezimalzahl mit 2 Nachkommstell
 
Hallo Jürgen,

mein Lösungsvorschlag ist kein Hexenwerk. Der SQL-Standard legt fest, dass arithmetische Operationen mit Integer-Werten einen Integer-Wert als Ergebnis haben. Da du auf die Nachkommastellen nicht verzichten willst, musst du einfach dafür sorgen, dass an der Division nicht nur Ganzzahlen beteiligt sind. Ich habe das aus didaktischen Gründen per CAST() gemacht. Alles andere dürfte deinen Versuchen recht ähnlich sehen.

Der Zusatz "as Wert" sorgt dafür, dass der im SELECT-Statement verwendete Ausdruck in der Ergebnismenge einen vernünftigen Namen trägt, über den du auch per FieldByName() zugreifen kannst.

In meinem Beispiel hatte ich einen Alias-Namen für die Tabelle vergeben. Diese Alias-Namen tragen sehr zur Lesbarkeit eines so umfangreichen Statement wie deinem bei:

SQL-Code:
SELECT (RIGHT(k.Datum, 2) + '.' + SUBSTRING(k.Datum, 5, 2) + '.' + LEFT(k.Datum, 4)),
  LTRIM(p.PersNr), CAST(ROUND(CAST(k.Wert AS FLOAT) / 60, 2) AS NUMERIC(10, 2)) AS Wert
FROM KtoRechWerte k, Personalstamm p
WHERE (k.PersId = p.Identifikation)
  AND ...
Außerdem fällt mir auf, dass du ein Datum als String im Format 'YYYY-MM-DD' speicherst. Günstiger wäre die Speicherung im von Pervasive SQL unterstützten Datentyp DATE. Du kannst das auch nachträglich noch ändern:

SQL-Code:
ALTER TABLE KtoREchWerte MODIFY COLUMN Datum DATE
Das hätte den Vorteil, dass du das Format der Ausgabe mit SET DATEFORMAT = dmy einfach umstellen könntest, was dein Statement nochmal vereinfachen würde:

SQL-Code:
SELECT k.Datum, LTRIM(p.PersNr), CAST(ROUND(CAST(k.Wert AS FLOAT) / 60, 2) AS NUMERIC(10, 2)) AS Wert
FROM KtoRechWerte k, Personalstamm p
WHERE (k.PersId = p.Identifikation)
  AND ...
Wenn du das testen möchtest, dann sicher mit einer Kopie der Tabelle KtoRechWerte, die du leicht über Export und Import erstellen kannst.

Freundliche Grüße

juergen 20. Jul 2007 21:26

Re: [SQL] Ganzzahl ändern in Dezimalzahl mit 2 Nachkommstell
 
Hallo,
habt vielen Dank für die Antworten und die für mich sehr hilfreichen Erklärungen. :thumb:

Das mit den Alias' ist dann ja ne schöne Erleichterung.
Nun, mir ist bewusst, dass ich aber um das Anlesen von Grundlagen nicht umhinkomme.
(Buch ist schon bestellt) :zwinker:

@ marabu
Das mit dem NICHT-Datumsformat in der Tabelle wurde aus Kompatibilitätsgründen zu verschiedenen DBMS, BS, Ländern, eingestellten DB-Normen und Import-Export-Interfaces/Funktionen so angelegt.
Durch Abbilden des Datums in einen String in dem Format YYYYMMDD (nicht YYYY-MM-DD) hat man letztendlich in der Summe mit weniger Problemen zu kämpfen.
Die Handhabung dieses Strings wird von nichts beinflusst, das Handling in Delphi oder woanders ist auch relativ einfach (wenn man sich dran gewöhnt hat) ;-)
Natürlich kanne es in gewissen Situaltionen anders herum hilfreicher sein. Es gibt also immer ein Für und Wider.

Allen ein schönes Wochenende!

mkinzler 21. Jul 2007 10:16

Re: [SQL] Ganzzahl ändern in Dezimalzahl mit 2 Nachkommstell
 
Zitat:

Das mit dem NICHT-Datumsformat in der Tabelle wurde aus Kompatibilitätsgründen zu verschiedenen DBMS, BS, Ländern, eingestellten DB-Normen und Import-Export-Interfaces/Funktionen so angelegt.
Durch Abbilden des Datums in einen String in dem Format YYYYMMDD (nicht YYYY-MM-DD) hat man letztendlich in der Summe mit weniger Problemen zu kämpfen.
Und genau darum sollte man das Datumsformat nehmen und das DBMS, OS,Bibliotheken die Wandlung erledigen zu lassen. Bei Verwendung von Strings hast du zudem das Problem, das u.U. falsch sortiert wird, DBMS-interne Datumsroutinen nicht greifen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:32 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