AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi TField.Size zur Laufzeit anpassen ohne doppeltes Öffnen der Query
Thema durchsuchen
Ansicht
Themen-Optionen

TField.Size zur Laufzeit anpassen ohne doppeltes Öffnen der Query

Ein Thema von RSE · begonnen am 15. Feb 2013 · letzter Beitrag vom 20. Feb 2013
Antwort Antwort
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#1

AW: TField.Size zur Laufzeit anpassen ohne doppeltes Öffnen der Query

  Alt 15. Feb 2013, 14:40
Die Datenbankfelder sind zur Designtime in die Queries importiert, um leichter darauf zugreifen zu können.
Man nennt die Felder, die schon zur Designtime angelegt wurden persistente Felder.
Persistente Felder haben das Problem, dass die Definitionen von denen der Datenbank abweichen können.
(Z.B. wenn Felder in der DB nachträglich verlängert wurden)

Bei persistenten Feldern in Delphi gibt es leider nur eine Alles-oder-Nichts-Strategie.
Entweder man hat persistente Felder oder man hat sie nicht und dann gelten die Felddaten aus der unterliegenden Datenbank.
Leider ist es nicht möglich im Objektinspektor gezielt einige Felddaten anzupassen (z.B. nur EditFormat ändern).

Bei diesen Nachteilen von persistenten Feldern, sollte man diese vermeiden wo es nur geht.
Der "leichtere Zugriff", weil Delphi für jedes persistente Feld eine Komponente bereitstellt, gleicht die Nachteile nicht aus.
Es gibt mindestens 5 Wege um auf ein Feld zuzugreifen:
Delphi-Quellcode:
var
  strName: string;
begin
  strName := Query.Fields[0].AsString;
  strName := Query.FieldByName('LastName').AsString; // bevorzugter Weg
  strName := Query.FieldValues['LastName'];
  strName := Query['LastName']; // inbesondere beim schreibenden Zugriff sinnvoll
  strName := QueryLastName.AsString; // nur bei persistenten Feldern
Also mein Rat:
Lösche die persistenten Felder und benütze die Variante "bevorzugter Weg" von oben.
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#2

AW: TField.Size zur Laufzeit anpassen ohne doppeltes Öffnen der Query

  Alt 15. Feb 2013, 17:43
Da es tausende Referenzen auf persistente Datenbankfelder in unserem Code gibt, kann ich diese nicht alle umarbeiten. Wir haben uns jetzt darauf geeinigt Meldungen auszugeben, wenn Differenzen in den Feldlängen auftreten und dann diese zu entfernen, bevor das Programm in den Produktiveinsatz kommt. Das ist keine schöne Lösung, aber bis die Neuimplementierung des gesamten Programms fertig ist, die nebenbei läuft, ist sie gut genug.
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#3

AW: TField.Size zur Laufzeit anpassen ohne doppeltes Öffnen der Query

  Alt 15. Feb 2013, 18:36
Ich würde zusätzlich auch empfehlen im Sourcecode vermehrt die Klasse TDataset zu benützen.
Ich vermute mal dass der Code strukturmässig so aussieht:
Delphi-Quellcode:
procedure TForm21.CalculateBruttowert;
begin
  Datamodule21.Query12.Edit;
  Datamodule21.Query12Bruttowert.Value := Datamodule21.Query12Nettowert.Value
    * (1.0 + DataModule13.Query1Mwst.Value / 100.0);
  ...
  Datamodule21.Query12.Post;
end;
Alles ist fest verdrahtet und unflexibel.
Jede Änderung zieht einen Rattenschwanz nach sich.
Und nun mit dem Dataset:
Delphi-Quellcode:
procedure TForm21.CalculateBruttowert(ds:TDataset; mwstprozent:double);
begin
  ds.Edit;
  ds['Bruttowert'] := ds.FieldByName('Bruttowert').AsFloat
    * (1.0 + mwstprozent / 100.0);
  ...
  ds.Post;
end;

// Aufruf
CalculateBruttowert(Datamodule21.Query12, DataModule13.Query1['Mwst']);
Jede Wette, es gibt Hunderte Stellen, die man so verbessern kann.
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#4

AW: TField.Size zur Laufzeit anpassen ohne doppeltes Öffnen der Query

  Alt 15. Feb 2013, 19:10
Du hast absolut recht, es gibt hunderte solcher Stellen - oder anders gesagt besteht unser gesamter Quellcode aus sowas. Und es gibt noch massig andere, viel schwerwiegendere Design-Flaws mit denen wir uns rumärgern. Ich habe z.B. schon tonnenweise globale Variablen entsorgt. Visuelle Vererbung wäre auch toll einsetzbar gewesen. Deswegen wird ja das ganze Programm neu entwickelt. Es hat einfach keinen Sinn, da noch etwas zu refaktorieren, wir müssen nur damit klarkommen, bis die neue Version fertig ist, also noch einige Monate.
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#5

AW: TField.Size zur Laufzeit anpassen ohne doppeltes Öffnen der Query

  Alt 15. Feb 2013, 20:14
Leider hat es aber auch was mit Performance zu tun. Der Zugriff über FieldbyName ist bis zu 4x langsamer als wenn man ein FeldObjektt benutzt. Deshalb verwenden wir zwar, ausser in datensensitiven Formularen zwar auch FieldByName, aber bei Schleifen mit entsprechenden Optimierungen, so dass es nur einen Aufruf ausserhalb der Schleifen gibt:

Delphi-Quellcode:
var
   QryBestandID : TField;
begin
   ...
   QryBestandId := QryBestand.FieldByName('Id');
   ...
   while not QryBestand.Eof do
   begin
      if QryBestandId.AsFloat ...
      ...
      qryBestand.Next;
   end;
end;
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#6

AW: TField.Size zur Laufzeit anpassen ohne doppeltes Öffnen der Query

  Alt 15. Feb 2013, 22:52
@Union: Genau, da spart man so einige Nanosekunden, weil der String nicht mit allen Feldnamen der Query verglichen werden muss - Buchstabe für Buchstabe. Das ist bei heutigen Rechnerleistungen schon ein erheblicher Performancegewinn. Aber ich erwische mich auch manchmal bei solchen "sinnigen" Optimierungen...

Das einzige, was es heute noch zu optimieren gilt, sind Netzwerkzugriffe, Festplattenzugriffe und vielleicht Bildausgaben. Und vielleicht verschachtelte Schleifen mit Millionen von Durchläufen. 3GHz sind 3 Milliarden Takte pro Sekunde, das Ganze in der Regel auf mehreren Kernen (die anderen Prozesse unterbrechen den Hauptprozess nicht mehr so oft = weniger zeitintensive Prozesswechsel notwendig). Wenn eine komplette Operation 10 Takte dauert, dann sollte man pro Operation dank Pipelining (Jede Operation ist in 10 Einzelschritte zerlegt - während der zweite Schritt der ersten Operation läuft, läuft parallel der erste Schritt der zweiten Operation - durch Abhängigkeiten kann es allerdings sein, dass die nächste notwendige Operation erst feststeht, wenn die vorige abgeschlossen ist, dann beginnt die nächste erst nach dem letzten Schritt/Takt der vorigen Operation) im Schnitt trotzdem nicht mehr als 2 bis 3 Takte rechnen müssen.

Das Vergleichen eines Buchstabens ist übrigens eine Operation. Bei einer durchschnittlichen Feldnamenlänge von 20 Buchstaben und unter der Annahme, dass die Feldnamen immer komplett verglichen werden müssten (was sie nicht müssen) und 20 Feldern pro Query, sind das im schlimmsten Fall 400 Operationen, nur um den richtigen Pointer zu finden - also ein Bruchteil einer Mikrosekunde. Worst-Case!
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."

Geändert von RSE (15. Feb 2013 um 22:58 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#7

AW: TField.Size zur Laufzeit anpassen ohne doppeltes Öffnen der Query

  Alt 15. Feb 2013, 23:12
@Union: Genau, da spart man so einige Nanosekunden, weil der String nicht mit allen Feldnamen der Query verglichen werden muss - Buchstabe für Buchstabe. Das ist bei heutigen Rechnerleistungen schon ein erheblicher Performancegewinn. Aber ich erwische mich auch manchmal bei solchen "sinnigen" Optimierungen...
Isoliert betrachtet hast Du natürlich Recht.

Wenn diese "Nanosekunden" sich allerdings addieren, kommt u.U. ganz schön was heraus - z.b. wenn es vorher 870 µs und hinterher 446 µs sind. Und sich dadurch die durchschnittliche Verarbeitungsdauer einer Einheit von 2,081 s auf 1,598 s reduziert. Und der Kunde 5000 Einheiten verarbeiten muss. Das ergibt eine Zeitersparnis von ca. 40 Minuten. Daher können die Mitarbeiter die Einheiten schneller abarbeiten und erzielen eine größere Performance. Bei 20-30 Mitarbeitern spart dadurch die Firma jeden Tag Geld durch den Performancegewinn. Unwesentlich, ich weiss
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:55 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