![]() |
Objecte / Datensatz(record)
Hallo,
ich erstelle beim öffnen einer Datenbanktabelle je Datensatz ein Objekt. In diesem Objekt erstelle ich ein Bitmap aus dem Inhalt des Datensatzes. Das funktioniert soweit auch alles schon ganz gut. Nun möchte ich aber auch auf Änderungen in der Tabelle oder auch auf Änderungen des Objektes reagieren. Und zwar soll das Bitmap des Objekts das zu einem bestimmten Datensatz gehört, neu gezeichnet werden wenn sich Werte ändern. bzw. soll der Datensatz aktualisiert werden wenn sich ein Objektwert ändert. Wie binde ich aber das Objekt an einen Datensatz aus der Tabelle. Es muss doch eine bessere Lösung geben wie Dataset.locate(...) und wie finde ich das Passende Objekt zu einem Datensatz??? Ich hoffe ich habe es einigermaßen verständlich beschrieben. Gruß EarlyBird |
Re: Objecte / Datensatz(record)
Du hast doch sicher einen Primary Key in der Tabelle. Also lade den PK ebenfalls in ein Feld deines Objektes (z.B. Id).
Dann verpasst du noch eine Save Methode in deine Klasse, und führst dort ein Update des Datensatzes aus. Gegebenfalls kannst Du dir sogar überlegen, auch ein Insert-Befehl zu implementieren, der dann ausgeführt wird falls Id z.B. den Wert 0 hat. So etwa:
Delphi-Quellcode:
procedure TMyClass.Save ;
begin sql := format('update tabelle set %s = :f1, %s = :f2 where id = %d',[Feldname1, Feldname2, id]) ; ds := TADOQuery.Create (nil) ; try ds.Connection := DeineAdoConnection ; ds.ParamByName (Feldname1).AsString := Wert1 ; ds.ParamByName (Feldname2).AsInteger := Wert 2 ; // ... ds.ExecSQL ; finally ds.free end ; end ; |
Re: Objecte / Datensatz(record)
Danke für den Tipp,
ist aber so nicht gewollt!! Dann hätte ich zwar die Tabelle in der Datenbank aktuell müsste aber ein refresh der Tabelle machen. Der geschwindigkeitsvorteil wäre wieder dahin. Außerdem ist mir immer noch nicht klar wie ich am schnellsten auf ein Objekt zugreife das einem bestimmten Datensatz entspricht!?!? Und umgekehrt. Wie kann ich sozusagen ein Objekt mit einem Datensatz verknüpfen?? Gruß EarlyBird |
Re: Objecte / Datensatz(record)
Kann ich in der Tabelle einen Pointer auf das Objekt speichern??
(Wie speichert man einen Pointer??) Wie wirken sich filtern und sortieren der Tabelle auf die Pointer aus?? wäre so ein zugriff auf die Objekte sicher?? Wenn ich die Objekte sortiere oder "move" , sind die Pointer in der Tabelle dann noch richtig zugeordnet? |
Re: Objecte / Datensatz(record)
Hallo,
wie jelly schon gesagt hatte, führt der Weg über den primary key und natürlich auch den Tabellennamen. Ändert sich der Objekt-Wert, machst du ein Update des Datenbank-Eintrages, ändert sich der DB-Eintrag, aktualisierst du das Objekt. Locate würde ich weglassen, mache das direkt mit einer Query. Das Dataset würde ich durch eine TClientDataset ersetzen, oder eine eigene Datenstruktur. Dein Problem ist eher "wenn sich in der Datenbank was ändert". Je nach DB gibt es da verschiedene Möglichkeiten (FB hat z.B. Events). Zur Not musst du Pollen (immer wieder abfragen, ob sich was geändert hat). Du könntest z.B. Änderungen in eine zusätzliche Protokolltabelle schreiben id, dbid, tablename, changedatetime Dann merkst du dir das aktuelle Datum/Uhrzeit und machst nen select * from protolol_table where changdatetime>=:deine_gemerkte_zeit Mit Pointern ? -> Kannst du vergessen. Heiko |
Re: Objecte / Datensatz(record)
Danke für den Beitrag.
Genau das UPDATE möchte ich halt nicht machen da ich nach jeder Änderung ein Refresh bräuchte. Ich will also die Daten direkt im Dataset ändern. (es gibt noch ein paar andere Gründe dafür) Und dazu muss ich möglichst schnell auf den entsprechenden Datensatz zugreifen. Es muss doch eine schnellere möglichkeit wie Locate geben. "Änderungen die in der Datenbank passieren" kann ich für meinen "speziellen Fall" erstmal unberücksichtigt lassen. Ausserdem ist mir immer noch nicht klar wie ich dann am schnellsten auf das Objekt zugreife. Wenn ich den primary Key im objekt speichere muss ich das Objekt immer noch suchen. Oder wie kann ich direkt darauf zugreifen?? with TmyObject(Table.FieldValue['PrimaryField']) .... geht ja leider nicht aber Table.bookmark := myObject.bookmark sollte doch funktionieren oder?? Gruß EarlyBird |
Re: Objecte / Datensatz(record)
Brauchst Du denn wirklich alle Datensätze auch in Form eines Delphi Objektes, oder brauchst Du nur das aktuell markierte im DBGrid. Bei letzterem brauchst du nicht suchen und auch keine Liste verwalten, sondern lediglich im AfterScroll Event deines Datasets dein Objekt des aktuellen Datensatzes erstellen.
|
Re: Objecte / Datensatz(record)
Hallo,
solange du direkt mit einem Dataset (TQuery, TTable) arbeitest, geht es doch gar nicht anders, als dass der Wert in der DB gespeichert wird. Mit könnte aber "CachedUpdates" was machen, also erst lokal speichern, dann mit einem Rutsch (ApplyUpdates) die Daten in die DB. Ich würde hier (weil von TClientDataSet keine Ahnung), eine eigene Datenstruktur nehmen. Wo sollen die Daten denn angezeigt werden? Falls DBGrid, kann man dann auch nen normales Grid nehmen, falls nicht, umso besser. Zum Objekt finden: - Objekte in einer eigenen Liste (TList) halten - sortieren nach dem primkey (quickssort) - und dann per BinSearch suchen Heiko |
Re: Objecte / Datensatz(record)
Die Daten werden nicht in einem Grid oder DBGrid dargestellt.
Ich werde mal kurz darstellen wofür das ganze gut ist. Ich muss Datensätze in einer vertikalen Ansicht darstellen. Ich nutze aus diversen Gründen kein Stringgrid unter anderem ist das scrollen durch die Datensätze zu langsam. Ein schnelles scrollen durch die Datensätze ist äußerst wichtig. Ich zeichne die Daten selbst in ein TBitmap und bin dabei so flexibel wie ich es benötige. Das scrollen funktioniert dann auch wesendlich schneller. Nun muss ich aber Änderungen in meinem "VerticalGridBild" machen können und das möglichst schnell. Dazu speichere pro Datensatz ein Bitmap mit Koordinaten in einem Objekt. ändern sich nun die Daten in der Tabelle kann ich dieses Bitmap einfach auf das "VerticalBild" kopieren. Auch eine mehrfachselection kann ich so gut darstellen. Auch das verschieben klappt schon ganz gut. "Nur" die Geschwindigkeit will ich halt noch optimieren. Ich hoffe die Darstellung macht das ganze etwas transparenter. Zitat:
(offline modus) Zitat:
Gruß EarlyBird |
Re: Objecte / Datensatz(record)
Hallo,
BinSearch sucht logarithmisch, das ist ein "bissel" schneller als nen FullTable Scan, umd es mal mit nem Datenbank-Begriff auszdrücken. Die Suche ähnelt hier einem Baum (binärbaum), nur das halt alle Einträge in einer Liste stehen. Heiko |
Re: Objecte / Datensatz(record)
Zitat:
Das geht aber stark auf Kosten des Hauptspeichers!! 10000 Bitmaps brauchen halt doch einige MBs. Besser wäre wohl EMF (Enhanced Meta File) zu benützen. Ein (Windows) Meta File ist sozusagen ein Playback aller Zeichenbefehle, die auf einen Canvas angewendet wurden. Es muss dabei nicht unbedingt in einer Datei gespeichert werden. Ich würde mich an deiner Stelle auf bessere Filtermöglichkeiten konzentrieren anstatt das DBGrid neu zu erfinden! Es ist doch viel sinnvoller die Datenmenge vor der Anzeige stark einzuschränken, als Tausende Datensätze anzuzeigen und das Scrollverhalten zu optimieren. Letztendlich müssen die Tausende Datensätze ja doch mindestens ein Mal eingelesen werden. Ändern sich die Daten im Hintergrund, wird der Cache wertlos und muss erneut aufgebaut werden. |
Re: Objecte / Datensatz(record)
Davon abgesehen macht es überhaupt keinen Sinn, einem Benutzer zisch tausend Datensätze in egal welcher Form vor die Nase zu knallen. Bau ein kluge Suchfunktion/Filterfunktion ein. Deine Anwender werden es dir danken.
|
Re: Objecte / Datensatz(record)
Zitat:
Es werden immer höchstens 2000 Datensätze sein. (von 10000 habe ich nie gesprochen) Zitat:
Hast Du eventuell einen Link zu mehr Infos dazu? Zitat:
Die maximal 2tausend Datensätze die ich anzeigen möchte sind leider nicht mehr zu Filtern. Gern würde ich auch auf das DBGrid zurückgreifen aber leider kann ich die Daten damit nicht vertical anzeigen. Das StringGrid habe ich auch schon getestet aber Leider ist das zu langsam. Beim scrollen von einem Datensatz werden allen Zellen neu gezeichnet das dauert halt. Zitat:
Es gibt schon Anwendungen wo es durchaus Sinn macht dem User schnellst möglich 2tausend Datensätze zu präsentieren. Vielen Dank für die Vielen Beiträge Gruß EarlyBird |
Re: Objecte / Datensatz(record)
Zitat:
Wenn du sie programmiertechnisch nicht filtern kannst, wie willst du dem Anwender zumuten, sich durch 2000 Datensaätze zu wühlen. Würd mich mal interessieren was für eine Anwendung du da programmierst. |
Re: Objecte / Datensatz(record)
"sind nicht mehr zu Filtern" ist vielleicht ein bisschen missverständlich.
Natürlich lassen sich Daten einer Tabelle Filtern, aber die max. 2tausend die ich geschrieben habe sind die, die schnell im Zugriff sein müssen. (der normal Fall werden auch eher zwischen 400 und 800 sein aber man sollte ja vom Maximum ausgehen) Die Daten werden farblich gekennzeichnet, nach verschiedenen Kriterien. So das die Datensätze sehr wohl schnell "zu durchwühlen" sind. (Ein roter Datensatz in 5 blauen fällt auch ohne lesen des Inhalts sehr schnell auf). Das ganze dient nicht hauptsächlich der Daten Eingabe sonder eher der Datensortierung. Die Sortierung geschieht aber "manuell" der User legt die Reihenfolge fest. Und in einer vertikalen Darstellung kann ich auf 3 Bildschirmen schon eine ganze Menge Daten nebeneinander anzeigen und behalte durch die Farben immer noch eine gewisse Übersicht. Ob das ganze jetzt die beste Lösung ist weiss ich auch noch nicht aber mit einem StringGrid geht das ganze halt zu langsam (das war mein erster Lösungsansatzt der auch erst ganz vielversprechend aussah). Zitat:
Außerdem drifte ich im Augenblick ganz vom eigentlichen Thema ab. Mir ist immer noch nicht klar wie ich einen Record an ein Objekt binde und umgekehrt? das muss doch irgendwie möglich sein. Gruß EarlyBird |
Re: Objecte / Datensatz(record)
Hallo,
wie schon 100 mal ;) gesagt, das einfachste ist der Primär-Schluessel des Records. Der ist bei dir ja wohl ein Integer, also
Delphi-Quellcode:
type
TMyClass = class iDBId: Integer; end; Heiko |
Re: Objecte / Datensatz(record)
Sorry wenn ich immer wieder Frage :wall:
Aber irgend wie macht es einfach nicht klick. Zitat:
Wie kann ich dann direkt das Objekt verwenden??
Delphi-Quellcode:
Das kann doch nicht die beste Lösung sein!?!?
for i := 0 to objects.count - 1 do
begin if MyClass.iDBId = 101 then .... ..... break; end; Dann brauche ich ja immer noch eine schleife :gruebel: |
Re: Objecte / Datensatz(record)
Hallo,
sortiere diese Liste nach der iDBId und buntze BinSearch zum Suchen. Ab D6 (?) gibt es auch TBucketList (Hash-Liste), die sowas ähnliches macht. Du könntest auch eine eigene Klasse von TBitmap ableiten und dort das iDBId eintragen. Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:27 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