Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Einfügen eines neues Feldes in AdoTable (https://www.delphipraxis.net/197546-einfuegen-eines-neues-feldes-adotable.html)

DavidKlimas 15. Aug 2018 13:18

Datenbank: Access (MDB) • Version: XE10.2 • Zugriff über: TAdoTable

Einfügen eines neues Feldes in AdoTable
 
Hallo zusammen,

ich möche zur laufzeit neue felder in meine Access Datenbank einfügen. Es gibt mehrere vorschläge in diesem Forum aber es klappt bei mir nicht.

Folgenden Code hab ich derzeit:

Code:
  var
  AdoTable1: TAdoTable;
  Field: TField;
  Str1: String;

  ...

  If ADOTable1.FieldList.Find(Str1) = nil then
  Begin
    ADOTable1.Active := False;
    Field := TIntegerField.Create(AdoTable1);
    Field.FieldName := Str1;
    Field.DataSet := AdoTable1;
    AdoTable1.FieldDefs.Add(Str1, ftInteger);
    AdoTable1.Active := true;  //-> Hier fehlermeldung das das Feld (Name im Str1) nicht gefunden wird
  End;

   ...
Weiss jemand warum das neue Feld nicht zugefügt wird ? Ich hab es auch mit "AdoTable1.Refresh" und sonstigem versucht, ohne erfolg.

Danke

David

himitsu 15. Aug 2018 13:42

AW: Einfügen eines neues Feldes in AdoTable
 
Dieses hier erstellt nur das TField für den Zugriff in deiner TAdoTable-Komponente,
aber ändert nicht die Datenbanktruktur und knallt dann natürlich, weil das Feld in der DB nicht existiert.

Ich weiß nicht was die Komponente macht, wenn du sowas versuchst, während sie "Active" ist.



Kannst du nicht irgendwo SQL-Statements ausführen?
https://msdn.microsoft.com/de-de/lib.../ff196148.aspx

DavidKlimas 15. Aug 2018 13:43

AW: Einfügen eines neues Feldes in AdoTable
 
Hallo Himitsu,

wenn die Datenbank aktiv ist bekomme ich den Fehler das ich die Struktur nicht verändern kann solang die Datenbank offen ist und benutzt wird.

Ich hab schon an das SQL gedacht aber mein ADOTable hat keineuntergeordnete SQL function... :-(

himitsu 15. Aug 2018 13:47

AW: Einfügen eines neues Feldes in AdoTable
 
SQL ausführen über sowas wie ein TAdoQuery?

Lässt du deine ADOTable die TField automatisch erstellen, oder sind die anderen Felder im Formdesigner angelegt?
Wenn Letzteres, dann muß dort dann natürlich auch noch dein Feld rein, sonst kannst du nicht darauf zugreifen. (nachdem das Feld auch in der DB erstellt wurde)

DavidKlimas 15. Aug 2018 13:55

AW: Einfügen eines neues Feldes in AdoTable
 
Die anderen Felder wurden mit Access erstellt. Du meinst ich muss das Field zweimal erstellen: in der DB und dem AdoTable ?

Ich greife auf das Feld mit folgendem Befehl zu :

Code:
  ...
  AdoTable1.FieldByName(Str1).Value
  ...
Mein AdoTable wird dynamisch geladen, ich hab also keine Komponente oder AdoQuery.

Code:
  AdoTable1 := TAdoTable.Create(Form1);
  ADOTable1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' + DataBaseWindowsPath + ';Persist Security Info=False';
  ADOTable1.TableName := 'MyTable';
  ADOTable1.Active := True;

himitsu 15. Aug 2018 16:09

AW: Einfügen eines neues Feldes in AdoTable
 
In der DB musst du das Feld schon anlegen,

ob auch nochmal in der Zugriffskomponente (hier TAdoTable), das kommt drauf an.



Bei den meisten solcher Komponenten gibt es ein entweder/oder.

Entweder du erstellst manuell die/alle nötigen die TField (und kannst da dann auch noch paar kleine Anpassungen vornehmen, wie z.B. Formatierung ala DisplayFormat oder die Size)
oder die Komponente erstellt die TField automatisch, anhand der abgefragten Tabelle oder des Ergebnisses eines Selects.

Sobald aber ein TField von dir erstellt wurde, dann wird die Automatik deaktiviert. (leider)


Sind also keine TField von dir erstellt worden (z.B. im Code oder über den Field-Editor im Formdesigner), dann brauchst du dieses neue Feld da auch nicht hinzuzufügen.

hoika 15. Aug 2018 17:33

AW: Einfügen eines neues Feldes in AdoTable
 
Hallo,
hier steht was dazu

http://forums.devshed.com/delphi-pro...le-940196.html
ziemlich weit unten (AdoTable.SQL.Add)

oder hier
https://stackoverflow.com/questions/...able-in-delphi
ganz unten

DavidKlimas 15. Aug 2018 18:16

AW: Einfügen eines neues Feldes in AdoTable
 
Hallo,

TAdoTable hat keine SQL function, und TAdoQTable is wahrscheinliche eine third-party komponente. Die gibt es bei mir nicht.

Nach langen probieren, geht es nun. Die lösung :

Code:
  var
  AdoTable1: TAdoTable;
  AdoConnection: TADOConnection;
  AdoQuery: TAdoQuery;
  Str1: String;

  ...

  If ADOTable1.FieldList.Find(Str1) = nil then
  Begin
    ADOTable1.Active := False;

    AdoConnection := TADOConnection.Create(Form1);
    AdoQuery := TAdoQuery.Create(Form1);
    AdoConnection.ConnectionString := AdoTable1.ConnectionString ;
    AdoConnection.LoginPrompt := False;
    AdoConnection.Connected := True;
    AdoQuery.Connection := AdoConnection;
    AdoQuery.Active := False;
    AdoQuery.SQL.Clear;
    Adoquery.SQL.Add('ALTER TABLE ' + TableName + ' ADD ' + FieldName + ' INTEGER');
    Adoquery.ExecSQL;
    Adoquery.Free;
    AdoConnection.Connected := False;
    AdoConnection.Free;

    AdoTable1.Active := true;
  End;

hoika 15. Aug 2018 18:37

AW: Einfügen eines neues Feldes in AdoTable
 
Hallo,
ja, siehe auch mein 2. Link.

himitsu 15. Aug 2018 20:27

AW: Einfügen eines neues Feldes in AdoTable
 
Delphi-Quellcode:
AdoQuery.Connection := AdoTable1.Connection;
:zwinker:

Und ein paar Ressourcenschutzblöcke können nie schaden. (Try-Finally ab Create bis Free)

haentschman 16. Aug 2018 05:54

AW: Einfügen eines neues Feldes in AdoTable
 
Moin...:P
Ich kann das so nicht stehen lassen...du willst ja aus den Fehlern lernen. :zwinker:

1. Beschäftige dich mal mit Begriff "Owner" http://docwiki.embarcadero.com/Libra...omponent.Owner
2. Beschäftige dich mit dem Begriff "Parent" (für Komponenten) http://docwiki.embarcadero.com/Libra...Control.Parent
3. Warum eine Table? Man kann das auch mit einer Query machen. Im OI trägt man das SQL ein. Vorteil: Wenn man andere Daten braucht, braucht man nur das SQL zu ändern (Bedingungen hinzufügen) und nicht die Komponente tauschen.

Delphi-Quellcode:
var
  AdoQuery1: TAdoQuery; // Auf Grund der Namensgebung sind das Komponenten auf dem Formular. Diese hällt die Gesamtdaten.
  //AdoConnection: TADOConnection; // wie himutsu schon sagte... "Query.Connection := AdoQuery1.Connection"
 
  Str1: String;
private // Abschnitt in der Form
  Query: TAdoQuery; // nicht auf die Form legen! Das nennt man dynamisch erzeugen. Name egal.

  ...

  if AdoQuery1.FieldList.Find(Str1) = nil then
  begin
    AdoQuery1.Close; // kürzer

    Query := TAdoQuery.Create(nil); // Owner = nil weil du gibst das Objekt selbst frei. (Query.Free)
    try
      Query.Connection := AdoQuery1.Connection;
      Query.SQL.Text := 'ALTER TABLE ' + TableName + ' ADD ' + FieldName + ' INTEGER'; // kürzer...Tablename = AdoQuery1
      Query.ExecSQL;
      // ggf. in try/except wenn man auf die Fehler reagieren will
    finally
      Query.Free;
    end;

    AdoQuery1.Open; // kürzer... Wenn du die Query nicht schließt, reicht ein AdoQuery1.Refresh
  end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:23 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