![]() |
Datenbank: XML (MyBase) • Zugriff über: TClientDataSet
TClientDataSet: AutoInc auch wirklich automatisch inc-en
Hallo, ich brauche in meinem Programm eine simple Datenbank, die nur lokal benutzt werden muss, aber Master/Detail Beziehungen unterstützen muss. Ich habe mich daher für das TClientDataSet entschieden und speichere damit zwei Tabellen ("UMTable" und "ArmTable") in zwei im Projektverzeichnis liegenden XML-Dateien ab.
UMTable hat folgende Fields: Pos (Autoinc, wurde automatisch auf "fareadonly", "faunique" gesetzt) MH_Name (string) FS_Typ (string) Name (string) ArmTable hat folgende Fields: Pos (siehe oben) UMID (integer) (würde über MasterSource und Masterfields auf UMTable.Pos gemappt, geht wunderbar) StartX (Float) StartY (Float) EndX (Float) EndY (Float) Meine Frage: Wenn ich nun das Programm starte und Werte bei UMTable oder ArmTable über ein DBGrid eingeben will, so sollte normalerweise automatisch ein neuer Wert bei Pos dastehen. (so bin ich es zumindest von Paradox Tabellen aus gewöhnt). Das Feld bleibt allerdings leer und erzeugt selbstverständlich beim Posten bzw. applyupdates eine Key Violation Exception. Was mache ich denn da falsch, dass da kein autoinc wert kommt? Falls ich den selbst erzeugen muss, wie mache ihc dass mit dem tclientdataset am besten? Vielen Dank für eure Hilfe!! :) |
Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en
Du musst Dir dein 'AutoInc' selbst basteln. Dazu dient das Event 'OnNewRecord'. Hier weist Du dem 'AutoInc'-Feld (Der Datentyp muss -glaube ich- ein TIntegerFeld sein) einfach einen neuen Wert zu, z.B. so:
Delphi-Quellcode:
Nun musst Du das private Feld 'fUniqueID' beim Einlesen der XML-Tabelle nur noch auf den höchsten Wert des Feldes 'IDFieldName' setzen und dann läuft das.
Procedure TDatamodule1.MyDataSetNewRecord (Sender : TDataset);
Begin inc (fUniqueID); Sender['IDFieldName'] := fUniqueID; End; |
Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en
Vielen Dank! Es funktioniert! Schade, dass es von Delphi's Seite her keine elegantere Lösung für ein solches, häufig auftretendes Problem gibt.
|
Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en
SMALLID, findest Du 2 Zeilen *unelegant*?
Eigentlich unterstützen alle DB einen AutoInc, Du verzichtest hier ausnahmsweise darauf, weil Du die MyBase-Möglichkeiten eines TClientDatasets für eine Mini-DB misbrauchst. Also ich verwende auch (selten und im Zusammenhang mit local memory tables) einen so gestrickten AutoInc, aber ein 'häufig auftretendes Problem' ist das sicherlich nicht. Schonmal an Access, ADS oder DBF gedacht? |
Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en
Hi nochmal. Ok vllt. habe ich dann doch was falsch verstanden. 2 Zeilen wären ja schon super! :D Ich setze aber am Anfang für jede Tabelle erstmal den funiqueid wert, indem ich durchiteriere mit
Delphi-Quellcode:
aber ggf. geht es noch anders?
//autoinc werte für UMTable und ArmTable initialisieren
fUMPosID := 1; UMTable.First; for i := 1 to UMTable.RecordCount do begin if UMTable.FieldByName('Pos').AsInteger > fUMPosID then fUMPosID := UMTable.FieldByName('Pos').AsInteger; UMTable.Next; end; fArmPosID := 1; ArmTable.First; for i := 1 to ArmTable.RecordCount do begin if ArmTable.FieldByName('Pos').AsInteger > fArmPosID then fArmPosID := UMTable.FieldByName('Pos').AsInteger; ArmTable.Next; end; Bisher habe ich immer nur Paradox Tabellen benutzt und in diesem Fall nutze ich MyBase, weil ich da weder BDE noch ADO Support auf dem Zielrechner brauche. Dachte eigentlich, dass jeder das TClientDataset für lokale DBs nimmt, oder ist da ODBC/ADO nach Access doch simpler? |
Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en
Zitat:
Zitat:
Delphi-Quellcode:
Im DataModuleCreate wird für alle Tabellen dann GetMaxID aufgerufen und der Wert in den privaten Feldern gespeichert. Noch einfacher ist es, die MaxID in der Tag-Eigenschaft der Tabelle zu speichern:
Function GetMaxID (aTable : TDataset; IDField : String) : Integer;
Var fField : TField; B : TBookmark; Begin Result := -maxInt; fField := aTable.FieldByName(IDField); aTable.DisableControls; aTable.GetBookmark (B); Try aTable.First; While not aTable.Eof Do Begin If Result < fField.AsInteger Then Result := fField.AsInteger; aTable.Next; End; Finally aTable.GotoBookmark (B); aTable.FreeBookmark (B); aTable.EnableControls; End; End;
Delphi-Quellcode:
Ich würd trotzdem Access nehmen. Ist doch schön stabil (bei einer Einzelplatzanwendung).
Procedure TMyDataModule.DataModuleCreate (Sender : TObject);
Begin Table1.Tag := GetMaxId (Table1); Table2.Tag := GetMaxId (Table2); Table3.Tag := GetMaxId (Table3); Table4.Tag := GetMaxId (Table4); Table1.OnNewRecord := TMyDataModuleNewRecrd; Table2.OnNewRecord := TMyDataModuleNewRecrd; Table3.OnNewRecord := TMyDataModuleNewRecrd; Table4.OnNewRecord := TMyDataModuleNewRecrd; End; Procedure TMyDataModule.DataModuleCreate (Sender : TDataset); Begin Sender.Tag := Sender.Tag + 1; Sender[IDField] := Sender.Tag; End; |
Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en
Das ist ja cool mit dem ADO/Access! Ich hatte immer gedacht, dass man da auch bei der Installation noch Komponenten in der Manier von BDE oder .NET Framework hinzufügen muss oder zumindest Office installiert sein muss. Peinlich Peinlich *rotwerd*, naja ich hatte bisher wie gesagt nur Paradox benutzt (weil ich auch bisher nur Delphi 4 Pro gekauft hatte und leider keine Mittel für ein neues Delphi da waren - jetzt hab ich aber 7 Pro hier und BDS2006 an der Uni :D) aber wenn das ADO so auch funktioniert werde ich ab jetzt lieber Access für sowas verwenden. Dann klappt's auch wieder mit'm AutoInc ;) :D Danke nochmal!
|
Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en
Moin Zusammen,
Zitat:
|
Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en
Hallo Chris,
wenn man bei der Erzeugung von Identitäten nicht auf die Unterstützung des Datenbanksystems zählen kann, dann sind schon deutlich mehr als zehn Zeilen Code nötig um einen Mehrbenutzerbetrieb zu ermöglichen. So darf z.B. das Programm keinen weiteren Programm-Instanzen den Zugriff auf die Konfigurationsdatei gestatten, solange das Konzept lediglich das Auslesen des Startzählers beim Programmstart vorsieht. Ist schon besser, wenn man mit AutoInc bzw Identity arbeitet. Freundliche Grüße |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:56 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