Frank Rothweiler
2011-04-16 14:11:26 UTC
Für eine automatisierte Datenbank-Konvertierung (Access –> Firebird)
benötige ich das Feld jeder Tabelle, das einen Primärschlüssel
darstellt. Ich greife über die dbGO-Komponenten (ADO) auf eine
Access-Datenbank zu.
Über Feldeigenschaften ist die Information darüber, ob ein Feld ein
AutoInc-Feld ist, abrufbar:
FOR i := 0 TO ADOdataset.FieldDefs.Count -1 DO
IF ADOdataset.FieldDefs[i].DataType = ftAutoInc THEN IndexFeld := i;
in einer Schleife über alle Felder (Spaltennamen) hinweg funktioniert.
Nun gibt es aber Tabellen, die zwar einen Primärschlüssel besitzen, aber
kein AutoInc-Feld. So z.B. wenn der Primärschlüssel zu einem Feld mit
Artikelnummern gehört. Wie finde ich in diesem Fall heraus, welche
Spalte einer Tabelle den Primärschlüssel darstellt?
Mittels der Attribute der Felddefinitionen ...
faHiddenCol, faReadonly, faRequired, faLink, faUnNamed, faFixed
... ist es nicht möglich, einen Primärschlüssel zu ermitteln.
Ich habe sogar bereits mit den Units ADODB_TLB und ADOX_TLB
herumexperimentiert (generiert aus Microsoft ADO Data Conrol 6.0 bzw.
Microsoft ADO Ext. 2.8 for DLL and Security), scheitere aber an den
Attributen:
FUNCTION TDatMod.TabelleAnlegen(Sender: TObject; TabName : WideString;
VAR Ergebnis : STRING) : BOOLEAN;
VAR
Table : _Table;
Column : _Column;
Catalog : _Catalog;
i,
PrimaryFeld : INTEGER;
PrimaryFeldName : WideString;
BEGIN
Result := FALSE;
...
Catalog := CoCatalog.Create;
Catalog.Set_ActiveConnection(ADOConMain.ConnectionObject);
Table := Catalog.Tables[TabName];
FOR i := 0 TO Table.Columns.Count -1 DO
IF Column.Attributes = adKeyPrimary
THEN
BEGIN
PrimaryFeld := i;
PrimaryFeldName := Table.Columns[i].Name;
END;
...
END;
In ADOX_TLB ist definiert:
const
adKeyPrimary = $00000001;
adKeyForeign = $00000002;
adKeyUnique = $00000003;
Zur Laufzeit hat Column.Attributes den Wert 2, wenn das Feld[i] einen
Primärschlüssel hat und gleichzeitig ein AutoInc-Feld ist. In der
anderen Tabelle, die lediglich eine Artikelnummer (LongInteger,
Primärschlüssel) und eine Warenbezeichnung (Text (200)) enthält, hat die
Artikelnummer-Spalte den Attributwert 3 und die Warentext-Spalte den
Wert 2. Ich blicke da ehrlich gesagt nicht so recht durch ...
benötige ich das Feld jeder Tabelle, das einen Primärschlüssel
darstellt. Ich greife über die dbGO-Komponenten (ADO) auf eine
Access-Datenbank zu.
Über Feldeigenschaften ist die Information darüber, ob ein Feld ein
AutoInc-Feld ist, abrufbar:
FOR i := 0 TO ADOdataset.FieldDefs.Count -1 DO
IF ADOdataset.FieldDefs[i].DataType = ftAutoInc THEN IndexFeld := i;
in einer Schleife über alle Felder (Spaltennamen) hinweg funktioniert.
Nun gibt es aber Tabellen, die zwar einen Primärschlüssel besitzen, aber
kein AutoInc-Feld. So z.B. wenn der Primärschlüssel zu einem Feld mit
Artikelnummern gehört. Wie finde ich in diesem Fall heraus, welche
Spalte einer Tabelle den Primärschlüssel darstellt?
Mittels der Attribute der Felddefinitionen ...
faHiddenCol, faReadonly, faRequired, faLink, faUnNamed, faFixed
... ist es nicht möglich, einen Primärschlüssel zu ermitteln.
Ich habe sogar bereits mit den Units ADODB_TLB und ADOX_TLB
herumexperimentiert (generiert aus Microsoft ADO Data Conrol 6.0 bzw.
Microsoft ADO Ext. 2.8 for DLL and Security), scheitere aber an den
Attributen:
FUNCTION TDatMod.TabelleAnlegen(Sender: TObject; TabName : WideString;
VAR Ergebnis : STRING) : BOOLEAN;
VAR
Table : _Table;
Column : _Column;
Catalog : _Catalog;
i,
PrimaryFeld : INTEGER;
PrimaryFeldName : WideString;
BEGIN
Result := FALSE;
...
Catalog := CoCatalog.Create;
Catalog.Set_ActiveConnection(ADOConMain.ConnectionObject);
Table := Catalog.Tables[TabName];
FOR i := 0 TO Table.Columns.Count -1 DO
IF Column.Attributes = adKeyPrimary
THEN
BEGIN
PrimaryFeld := i;
PrimaryFeldName := Table.Columns[i].Name;
END;
...
END;
In ADOX_TLB ist definiert:
const
adKeyPrimary = $00000001;
adKeyForeign = $00000002;
adKeyUnique = $00000003;
Zur Laufzeit hat Column.Attributes den Wert 2, wenn das Feld[i] einen
Primärschlüssel hat und gleichzeitig ein AutoInc-Feld ist. In der
anderen Tabelle, die lediglich eine Artikelnummer (LongInteger,
Primärschlüssel) und eine Warenbezeichnung (Text (200)) enthält, hat die
Artikelnummer-Spalte den Attributwert 3 und die Warentext-Spalte den
Wert 2. Ich blicke da ehrlich gesagt nicht so recht durch ...