Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Field-Struktur/Namen zur Laufzeit ändern (https://www.delphipraxis.net/62694-field-struktur-namen-zur-laufzeit-aendern.html)

Deep Blue 8. Feb 2006 11:11

Datenbank: Paradox • Version: 7 • Zugriff über: via BDE

Field-Struktur/Namen zur Laufzeit ändern
 
Hallo,
ich bin kurz vorm Verzweifeln...
Kann mir jemand sagen, ob es einen einfachen Weg gibt, in einer gefüllten Paradox-Tabelle via TTable-Komponente die Spalten-Struktur zur Laufzeit zu ändern. Ich möchte eine datenbank dynamisch anpassen oder bearbeiten können. Aber eben nicht die Zeilen/Records sondern die Spalten/Fields. Z.B. einfach den FieldName ändern. Im Prinzip geht das ja über CreateTable. Aber die löscht den Inhalt der Tabelle. Und mir sträuben sich die Nackenhaare, wenn ich gezwungen bin, eine leere Tabelle zu erstellen, die Fieldstruktur der vorhandenen Tabelle zu kopieren und anzupassen, CreateTable aufzurufen und dann alle Records zu verschieben.

Es wäre Toll wenn mir jemand helfen könnte.
Schonmal Danke im Voraus...
Bis dann

RavenIV 8. Feb 2006 12:51

Re: Field-Struktur/Namen zur Laufzeit ändern
 
wir hatten diese Anforderung auch schon.

da wir aber auch keine bessere Idee hatten, haben wir die Tabelle kopiert, gelöscht, neu angelegt und die Daten wieder zurückkopiert. Das System funktioniert heute noch.

mkinzler 8. Feb 2006 13:02

Re: Field-Struktur/Namen zur Laufzeit ändern
 
Ich kenn mich mit dem LokalSQl der BDE nicht (mehr) so aus, aber eigentlich sollte es mit SQL klappen:

SQL-Code:
ALTER TABLE <table> ALTER <name> to <newname>;

Deep Blue 9. Feb 2006 08:15

Re: Field-Struktur/Namen zur Laufzeit ändern
 
Hi,
danke für die postings...
Wenn es per SQL die Möglchkeit gibt, die Feldstruktur anzupassen, sollte es doch prinzipiell auch über die TField-Objekte oder die TTable-Komponente möglich sein?
Vielleicht ist einfach irgend ein Flag nicht gesetzt, das ich nicht kenne...
Bis dann

eddy 9. Feb 2006 09:23

Re: Field-Struktur/Namen zur Laufzeit ändern
 
Hallo Deep Blue,

mit AppFld habe ich dieses Problem ohne SQL-Nutzung gelöst. Man kann natürlich auch vor der Schleife "Tabellenstruktur übernehmen" Felder einfügen. Das macht aber nur Sinn, wenn man den Primärindex ändern will. Bei mir beginnt jede Datenbank mit einem Feld ID vom Typ ftAutoInc, der als Primärindex dient.

Delphi-Quellcode:

  // Strukturanpassung von Adressen.DB (Freifeld1..4)
  UP_DBActiv(Tab2, SessN, DataPath, fnAdr);        // TTable Tab2 öffnen
  if Tab2.FindField('Freifeld1') = nil then begin  // wenn Feld Freifeld1 nicht gefunden
    AppFld(Tab2, 'Freifeld1', ftString, 60);       // DB-Struktur mit neuen Namen ergänzen
    AppFld(Tab2, 'Freifeld2', ftString, 60);
    AppFld(Tab2, 'Freifeld3', ftString, 60);
    AppFld(Tab2, 'Freifeld4', ftString, 60);
    // danach Index für DB neue aufbauen
    UP_DBActiv(Tab1, SessN, SysPath, fnDBIdx);
    FAllgUP2.UP_GenIdx(Tab1, Tab2, ChangeFileExt(fnAdr, ''));
    Tab1.Close;
  end;
  Tab2.Close;



procedure TFUPK.AppFld(tab : TTable; fldname : string; fldtyp : TFieldType; fldsize : integer);
var i:Integer;
    alterTabellenName:String;
    ztab, qtab : TTable;
begin
  tab.Active := false;
  qtab := TTable.Create(self);
  ztab := TTable.Create(self);
  try
    qtab.DatabaseName := tab.DatabaseName;
    qtab.TableName := tab.TableName;
    qtab.SessionName := SessN;
    qtab.Active := true;
    FInput.lblRecNo.Caption := IntToStr(qtab.RecordCount) +cblk+ FU(cdatensaetze);

    ztab.DatabaseName := tab.DatabaseName;
    ztab.SessionName := SessN;
    ztab.TableType := ttParadox;
    ztab.TableName := 'tmp_' + tab.TableName;

    ztab.FieldDefs.Clear;
    //Tabellenstruktur übernehmen
    for i:=0 to qTab.Fields.Count-1 do
      ztab.FieldDefs.Add( qTab.Fields[i].FullName,
                          qTab.Fields[i].DataType,
                          qTab.Fields[i].Size,
                          qTab.Fields[i].Required);
    try
      //neue Felder hinzufügen
      ztab.FieldDefs.Add(fldname, fldtyp, fldsize, false);
      ztab.CreateTable;

      qtab.Active:=false;
      ztab.Active:=false;

      // FInput nur für Anzeige eines Textes
      FInput.Tag := 102;
      FInput.lblHinw102.Caption := FU(cdaten)+cstruktur +cblk+ cvon +cblk+ qtab.TableName +cblk+ cwird +cblk+ cangepasst;
      FInput.lblRecNoText.Caption := FU(cbitte) +cblk+ cwarten +cblk+ c4pkt+c4pkt;
      FInput.Show;

      Batchmove1.Mode:=batAppend;
      i := Batchmove1.RecordCount;
      Batchmove1.Source := qtab;
      Batchmove1.Destination := ztab;
      Batchmove1.Execute;
      FInput.Hide;

    //  Showmessage('ztab : ' + ztab.TableName); // nur für Test
    //  Showmessage('qtab: ' + qtab.TableName);
      alterTabellenName:=qTab.TableName;

      qTab.Active:=false;
      qTab.DeleteTable;
      ztab.RenameTable(alterTabellenName);
      ztab.Active:=False;
    except
      qtab.Active:=false;
      ztab.Active:=false;
    end;
  finally; //wird auf jeden Fall ausgeführt, auch bei exit
    qtab.Close;
    ztab.Close;
    qtab.Destroy;
    ztab.Destroy;
  end;
end;
Variante ist getestet und hat sich bewährt, insbesondere zur automatischen Strukturanpassung beim Nutzer.

Vielleicht hilfts Dir weiter.

mfg
eddy

Deep Blue 10. Feb 2006 19:15

Re: Field-Struktur/Namen zur Laufzeit ändern
 
Hallo Eddy,
danke für dein posting.
Etwas ähnliches schwebte mir auch vor. Nur hatte ich gehofft, daß es einen etwas effizienteren Weg für das Problem gäbe, als das hin und her kopieren der ganzen Tabelle, die ja durchaus auch mal sehr groß werden kann. Ich muß mich wohl damit abfinden, daß es wohl in der TTable-Klasse keine Möglichkeiten gibt, um die Tabellenstruktur einer nicht-leeren Tabelle einfach zu ändern. Evtl. liegt es ja auch daran, daß man in den Fields-Methoden direkt mit den Namen der Fields arbeiten kann. Damit sind die Namen direkt im code enthalten und lassen sich zur Laufzeit nur schwer ändern. Ich kann mir aber nicht vorstellen, daß kein Bedarf daran besteht, flexible, dynamische Tabellenstrukturen zur verfügung zu haben...

Danke nochmal für eure Ideen.
Bis bald

mkinzler 10. Feb 2006 19:35

Re: Field-Struktur/Namen zur Laufzeit ändern
 
Was spricht gegen den Einsatz von SQL?

Deep Blue 12. Feb 2006 17:27

Re: Field-Struktur/Namen zur Laufzeit ändern
 
Im Prinzip spricht nichts gegen SQL. Ich würde nur ganz gern bei reinem Object Pascal bleiben. Ich verwende in meinen Projekten nur sehr ungern z.B. Scriptsprachen oder ähnliches. Wenn ich gezwungen bin mal in C++ zu programmieren hasse ich auch den zwangsläufigen Einsatz dieser unsäglichen Makros.
Aber, wie gesagt, im Prinzip spricht nichts dagegen SQL einzusetzen. Ich würde nur gern verstehen, warum die Fieldstruktur einer nicht-leeren Tabelle zwar mit SQL aber nicht mit den Komponenten der BDE geändert werden kann.
Bist du sicher, daß "Alter Table" auf nicht-leere Tabellen angewendet werden kann?
Bis dann

Frank Borland 13. Feb 2006 10:46

Re: Field-Struktur/Namen zur Laufzeit ändern
 
Moin moin,

Probleme im DB- Design werden umso schlimmer, je größer die Anhängigkeiten innerhalb der DB selber sind.
Das ist bei Paradox eher nicht der Fall :???:
Während das Erweitern einer Struktur (alter tabelle add feldname feldtyp ...) immer unproblematisch sein sollte ist das Anpassen einer Struktur eine defizile Angelegenheit. Die Daten im betroffenen Feld (Spalte) müssen umgespeichert werden und dann auch in das neue Feld passen. Ganz nebenbei können davon Indexe, stored procudures,views oder trigger betroffen sein die direkt abhängig vom Vorhandensein des zu ändernden Feldes sind.
Manchmal bastelt der Kunde einen View mit genau diesem Feld und Du wirst es nicht los. Jedenfalls nicht so leicht.

Gruß

Malte

Deep Blue 15. Feb 2006 09:53

Re: Field-Struktur/Namen zur Laufzeit ändern
 
Hallo zusammen,
danke nochmal für eure postings...
Ich hab mich entschieden beim Hinzufügen oder einer Namensänderung eines Fields via BDE die gesamte Tabelle umzukopieren. Ist ziemlich ineffizient, aber bleibt wohl nichts übrig...
Bis dann


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