AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi TClientDataSet: AutoInc auch wirklich automatisch inc-en
Thema durchsuchen
Ansicht
Themen-Optionen

TClientDataSet: AutoInc auch wirklich automatisch inc-en

Ein Thema von SMALLID · begonnen am 1. Jan 2007 · letzter Beitrag vom 2. Jan 2007
Antwort Antwort
SMALLID

Registriert seit: 10. Aug 2004
78 Beiträge
 
#1

TClientDataSet: AutoInc auch wirklich automatisch inc-en

  Alt 1. Jan 2007, 15:26
Datenbank: XML (MyBase) • Zugriff über: TClientDataSet
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!!
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en

  Alt 1. Jan 2007, 15:31
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:
Procedure TDatamodule1.MyDataSetNewRecord (Sender : TDataset);
Begin
  inc (fUniqueID);
  Sender['IDFieldName'] := fUniqueID;
End;
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.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
SMALLID

Registriert seit: 10. Aug 2004
78 Beiträge
 
#3

Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en

  Alt 1. Jan 2007, 17:00
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.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en

  Alt 1. Jan 2007, 22:28
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?
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
SMALLID

Registriert seit: 10. Aug 2004
78 Beiträge
 
#5

Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en

  Alt 2. Jan 2007, 02:44
Hi nochmal. Ok vllt. habe ich dann doch was falsch verstanden. 2 Zeilen wären ja schon super! Ich setze aber am Anfang für jede Tabelle erstmal den funiqueid wert, indem ich durchiteriere mit

Delphi-Quellcode:
  //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;
aber ggf. geht es noch anders?

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?
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#6

Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en

  Alt 2. Jan 2007, 09:05
Zitat von SMALLID:
Hi nochmal. Ok vllt. habe ich dann doch was falsch verstanden. 2 Zeilen wären ja schon super! Ich setze aber am Anfang für jede Tabelle erstmal den funiqueid wert, indem ich durchiteriere mit
Na gut, die Initialisierung ist vielleicht noch dazuzurechnen.
Zitat von SMALLID:
...
aber ggf. geht es noch anders?
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?
Erstens geht es einfacher und zweitens ist ADO sowieso auf jedem Windows-PC installiert. Ich würde persönlich (aber nur bei Einzelplatzanwendungen) Access per ADO verwenden. Für Standard-Anwendungen reicht das Dicke und macht die Entwicklung zum Kinderspiel.

Delphi-Quellcode:
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;
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:
Delphi-Quellcode:
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;
Ich würd trotzdem Access nehmen. Ist doch schön stabil (bei einer Einzelplatzanwendung).
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
SMALLID

Registriert seit: 10. Aug 2004
78 Beiträge
 
#7

Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en

  Alt 2. Jan 2007, 11:48
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 ) 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 Danke nochmal!
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.117 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en

  Alt 2. Jan 2007, 12:45
Moin Zusammen,

Zitat von alzaimar:
Na gut, die Initialisierung ist vielleicht noch dazuzurechnen.
wobei man ja die zuletzt benutzte ID auch einfach in einer Konfigurationsdatei speichern könnte.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#9

Re: TClientDataSet: AutoInc auch wirklich automatisch inc-en

  Alt 2. Jan 2007, 22:04
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
  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 07:25 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