Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Feldtyp von float zu Numeric ändern (https://www.delphipraxis.net/153532-feldtyp-von-float-zu-numeric-aendern.html)

raphaelm 6. Aug 2010 14:07

Datenbank: Firebird • Version: 1.5.6 • Zugriff über: IBX

Feldtyp von float zu Numeric ändern
 
Hallo,

ich will die Datenfelder einer Datenbank von Float zu Numeric aufgrund der Rundungsdifferenzen ändern.
Leider funktioniert das nicht über "alter table <table> alter <field> type <newtype>".


Deshalb hier mein Versuch:

Delphi-Quellcode:
var q,q1 : TIBQuery;
    i,j : integer;
    tables : TStringlist;
    fields : Tstringlist;
begin
  q := TIBQuery.Create(nil);
  q1 := TIBQuery.Create(nil);

  tables := TStringlist.Create;
  fields := TStringlist.Create;
  try
    q1.Database := IBDatabase1;
    q.Database := IBDatabase1;
    IBDatabase1.GetTableNames(tables);
    for i := 0 to tables.Count-1 do begin
      IBDatabase1.GetFieldNames(tables[i],fields);
      q1.close;
      q1.SQL.Text := 'select * from '+tables[i];
      q1.open;
      memo1.Lines.Add('Table :'+tables[i]+' - '+inttostr(i+1)+'/'+inttostr(tables.Count-1));
      for j := 0 to fields.Count-1 do begin
        if q1.FieldByName(fields[j]).DataType = ftFloat then begin
          memo1.Lines.Add('Field :'+fields[j]+' - '+inttostr(j+1)+'/'+inttostr(fields.Count-1));
          //try

            q.SQL.Text := 'alter table '+tables[i]+' alter '+fields[j]+' to '+fields[j]+'tmp';
            memo1.Lines.Add(q.sql.text);
            q.ExecSQL;

            q.SQL.Text := 'alter table '+tables[i]+' add '+fields[j]+' NUMERIC(10,5)';
            memo1.Lines.Add(q.sql.text);
            q.ExecSQL;

            q.SQL.Text := 'update '+tables[i]+' set '+fields[j]+' = '+fields[j]+'tmp';
            memo1.Lines.Add(q.sql.text);
            q.ExecSQL;

          //except
          //end;
        end;
      end;
    end;
  finally
    q1.Free;
    q.free;
    fields.Free;
    tables.Free;
  end;
  IBTransaction1.Commit;
end;

Das ganze sieht laut der Ausgabe im Memofeld auch ganz gut aus (die Eingabe der Statements funktioniert über Flame Robbin), allerdings schreibt er die Werte in der Datenbank in andere Felder (anscheinend alphabetisch darauf folgende Felder).

Datenbank: Firebird 1.5.6
Zugriff über: IBX
Delphi 6

Gegenüber einem anderen Ansatz wäre ich auch nicht abgeneigt.

himitsu 6. Aug 2010 14:20

AW: Feldtyp von float zu Numeric ändern
 
Zitat:

Leider funktioniert das nicht über "alter table <table> alter <field> type <newtype>".
Und warum funktioniert das nicht ... gibt's eventuell irgendwelche hilfreichen Fehlermeldungen?


Muß das nur einmal passieren?

- Tabellendaten exportieren
- die Tabelle leeren
- den Typ ändern (notfalls kann man immernoch das Feld löschen und neu erstellen)
- die alten Daten wieder importieren

hoika 6. Aug 2010 14:22

AW: Feldtyp von float zu Numeric ändern
 
Hallo,

warum soll es bei Numeric keinen Rundungsdifferenzen geben ???


Heiko

raphaelm 6. Aug 2010 21:20

AW: Feldtyp von float zu Numeric ändern
 
Zitat:

Zitat von hoika (Beitrag 1040039)
Hallo,

warum soll es bei Numeric keinen Rundungsdifferenzen geben ???


Heiko


Zitat:

... the NUMERIC definition means exactly the precision requested (total number of digits)
Quelle: http://www.firebirdsql.org/manual/mi...ata-types.html

Beim Versuch mit dem alter Befehl kam ein conversion error. Die genaue Meldung poste ich noch mal.

mkinzler 6. Aug 2010 21:26

AW: Feldtyp von float zu Numeric ändern
 
Wenn man eine Zahl auf 5 Stellen hintern Komma rundet ist diese genauer als eine Genauigkeit auf 7 oder 15 Stellen?

raphaelm 9. Aug 2010 07:40

AW: Feldtyp von float zu Numeric ändern
 
Zitat:

Zitat von mkinzler (Beitrag 1040098)
Wenn man eine Zahl auf 5 Stellen hintern Komma rundet ist diese genauer als eine Genauigkeit auf 7 oder 15 Stellen?

Mir geht es darum:

Wenn ich in ein Float Feld z.B 4711.90 schreibe steht nachher 4711.899902 drin (aufgrund der binären Representation)

Wenn ich das ganze in ein Numeric(10,5) Feld schreibe, stehen nachher auch exakt die 4711.90 in dem Feld.


Hier noch die Meldung für den alter Befehl:

Conversion from base type FLOAT to BIGINT is not supported

mkinzler 9. Aug 2010 07:47

AW: Feldtyp von float zu Numeric ändern
 
Da ist der Weg über das neue Feld der richtige.

himitsu 9. Aug 2010 07:59

AW: Feldtyp von float zu Numeric ändern
 
Und wenn du es direkt versuchst, also irgendwie so?
Delphi-Quellcode:
q.SQL.Text := 'ALTER TABLE '+tables[i]+' CHANGE '+fields[j]+' '+fields[j]+' NUMERIC(10,5)';

mkinzler 9. Aug 2010 08:06

AW: Feldtyp von float zu Numeric ändern
 
Dann kommt ja der von ihm genannte Fehler

himitsu 9. Aug 2010 08:10

AW: Feldtyp von float zu Numeric ändern
 
ups, das im Text hatte ich grade nicht nochmal mitbekommen
und in dem Quellcode macht er's ja anders.

mkinzler 9. Aug 2010 08:12

AW: Feldtyp von float zu Numeric ändern
 
Mit dem macht er es ja, da ein Wechsel des Type mit dem fehler quittiert wird

himitsu 9. Aug 2010 08:28

AW: Feldtyp von float zu Numeric ändern
 
Zitat:

Zitat von raphaelm (Beitrag 1040031)
Das ganze sieht laut der Ausgabe im Memofeld auch ganz gut aus (die Eingabe der Statements funktioniert über Flame Robbin), allerdings schreibt er die Werte in der Datenbank in andere Felder (anscheinend alphabetisch darauf folgende Felder).

Kann es sein, daß Flame Robbin die Felder indiziert, dann über diese Indize auf die DB zugreift,
dazu dann noch den Umbau der Tabelle nicht beachtet/mitbekommt und so die falschen Indize verwendet?

raphaelm 9. Aug 2010 08:43

AW: Feldtyp von float zu Numeric ändern
 
Das Verhalten habe ich nicht mit Flame Robin, sondern mit den IBX Komponenten (auch nach einem commit zwischen den Befehlen). Wenn ich die Befehle nacheinander in Flame Robin ausführe funktioniert es.

Ich probiers nun mal mit den UIB Komponenten. Sonst greife ich zur Not auf den Textexport und Reimport zurück.

mkinzler 9. Aug 2010 08:45

AW: Feldtyp von float zu Numeric ändern
 
Welche Komponente verwendest du TIBScript?

raphaelm 9. Aug 2010 08:54

AW: Feldtyp von float zu Numeric ändern
 
IBQuery

mkinzler 9. Aug 2010 08:55

AW: Feldtyp von float zu Numeric ändern
 
Für Skripte sollte man aber die obige Komponente verwenden

hoika 9. Aug 2010 09:58

AW: Feldtyp von float zu Numeric ändern
 
Hallo,

noch was anderes.

Alter Table und Update dürfen nicht in der gleichen Transaktion verwendet werden.
Laut einem der Core-Entwickler (Yemanov ?) ist das "per Design".

Das dadurch die DB in einem "halbgaren" Zustand bleibt, wenn das Update nicht komplett
ausgeführt werdne kann, ist mir klar.
Hatte aber gerade das gleiche Problem (mal hier suchen, vor 1-2 Wochen).


Heiko

raphaelm 9. Aug 2010 11:03

AW: Feldtyp von float zu Numeric ändern
 
Danke Heiko, das wars.

Die UIB Komponenten verhielten sich wie die IBX Komponenten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:40 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-2025 by Thomas Breitkreuz