Der folgende Beitrag dient dazu Informationen über die diversen Felder in den Tabellen Ihrer Datenbank in einer Verwaltungstabelle abzuspeichern, um einerseits Informationen zu haben, welche Felder es gibt, andererseits um festzustellen, welche durch das Programm erzeugt worden sind und welche benutzerspezifisch sind.
Natürlich haben die meisten Datenbanken Ihr eigenes Dictionary, aber diese enthalten immer alle Informationen über Felder / Indizes – egal, ob die Felder von Ihnen bzw. dem Programm oder dem Anwender hinzugefügt worden sind.
Um diesen Problem in den Griff zu bekommen, lohnt sich die Anlage einer eigenen Tabelle ‚Verwaltung‘, die wie folgt aufgebaut ist:
Tabelle: String, 80
Feldname: String, 80
Feldtyp: String, 20
Feldlaenge: Integer
Dies kann natürlich an Ihre Gegebenheiten angepasst oder erweitert werden, je nachdem welche Infos Sie aufnehmen möchten.
Nachdem die Tabellen Ihrer Datenbank angelegt sind, führen Sie folgenden Code aus. Dieser Code (Basis, aber ausbaufähig) prüft, ob schon Informationen in ‚Verwaltung‘ abgelegt sind. Wenn nicht, so wird die Datenbank (hier eine Nexus-DB) gescannt und alle Informationen über Tabellen + Felder der Verwaltungstabelle hinzugefügt:
procedure Checkverwaltung;
var mytable:TnxTable; tableList:TStringlist; i,x:Integer;
_datasize: Integer;
begin
tableVerwaltung.open; // unsere Verwaltungstabelle
tableverwaltung.First;
if tableverwaltung.eof then // noch keine Tabelleninformationen vorhanden, also scannen + einlesen
begin
tableList:=TStringlist.create; // speichert die Tabellennamen
DatabaseVeox.GetTableNames( TableList );
// Nexus-spezifisch, prüfen Sie bei Ihrer DB, wie Sie eine Liste aller
// enthaltenen Tabellen erhalten;
for i := 0 to TableList.Count – 1 do
begin
mytable:=TnxTable.Create(nil); // Tabelle dynamisch erzeugen
mytable.TableName:=tableList.Strings[i];
mytable.Database:=DatabaseVeox;
mytable.name:=tableList.Strings[i];
mytable.Open;
for x := 0 to mytable.FieldCount – 1 do
begin
tableVerwaltung.Insert;
tableVerwaltung.FieldByName(‚tabelle‘).AsString:=mytable.Name;
tableVerwaltung.FieldByName(‚Feldname‘).AsString:=mytable.Fields[x].FieldName;
case mytable.Fields[x].DataType of
ftGuid: tableVerwaltung.FieldByName(‚Feldtyp‘).AsString:=’Guid‘;
ftAutoInc: tableVerwaltung.FieldByName(‚Feldtyp‘).AsString:=’Autoinc‘;
ftDate: tableVerwaltung.FieldByName(‚Feldtyp‘).AsString:=’Date‘;
ftDateTime: tableVerwaltung.FieldByName(‚Feldtyp‘).AsString:=’Datetime‘;
ftFloat: tableVerwaltung.FieldByName(‚Feldtyp‘).AsString:=’Float‘;
ftInteger: tableVerwaltung.FieldByName(‚Feldtyp‘).AsString:=’Integer‘;
ftMemo: tableVerwaltung.FieldByName(‚Feldtyp‘).AsString:=’Memo‘;
ftString: tableVerwaltung.FieldByName(‚Feldtyp‘).AsString:=’String‘;
// weitere Feldtypen fall nötig hinzufügen
else
tableVerwaltung.FieldByName(‚Feldtyp‘).AsString:=’Unknown‘;
end;
_datasize:=mytable.Fields[x].DataSize;
if mytable.Fields[x].DataType=ftString then
Dec(_datasize);
// Datasize ist bei Stringtypen immer +1 als die tatsächliche Größe
// generell oder nur bei NexusDB?
tableVerwaltung.FieldByName(‚Feldlaenge‘).AsInteger:=_datasize;
tableVerwaltung.post;
end;
mytable.Close;
mytable.Free;
end;
tableVerwaltung.close;
tablelist.Free;
end;
end;
Datasize, Datatype, fieldname… sollten bei allen DB unter Delphi funktionieren
Fügen Sie zu einem späteren Programm neue Datenbankfelder (oder Änderungen) ein (durch), so aktualisieren Sie die Verwaltungstabelle entsprechend. Vom Benutzer hinzugefügte Felder werden dagegen nicht gespeichert, so dass immer eine saubere Trennung möglich ist.
Ebensfalls erweitern könnte man obiges Beispiel noch um Try…Except – Blöcke, um mögliche Probleme abzufangen. Ebenso beinhaltet obiges Beispiel noch keine Indexfeld-Informationen, ist also noch ausbaufähig.
Eine solche Tabelle kann dann natürlich auch prima dazu dienen, um entsprechende Prüfroutinen einzubauen, ob alle notwendigen Felder beim Kunden vorhanden sind und natürlich auch als Ausgangsbasis für Datenbank- / Tabellenerweiterungen.