Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi TADOQuery Primary Key auslesen (https://www.delphipraxis.net/147457-tadoquery-primary-key-auslesen.html)

Ducksoul 9. Feb 2010 09:56

Datenbank: Access • Zugriff über: ADO

TADOQuery Primary Key auslesen
 
Hallo,

beim Auslesen der Tabellenstruktur in der Datenbank bin ich auf das Problem gestoßen, dass ich nicht an den Primary Key herankomme.
Die Daten werden bis jetzt wie folgt ausgelesen:

Delphi-Quellcode:
    ...
    i := 0;
    slCodeMaster := TStringlist.Create;
    slTableOne := TStringlist.Create;
    ExtractConstantIntoStringList(CodeMaster, slCodeMaster);

    query_ex.SQL.Clear;
    query_ex.SQL.Add('SELECT * FROM Kunde');
    query_ex.Open;
    query_ex.First;

    while not query_ex.Eof do
    begin
      slTableOne.Add(query_ex.Fields[i].DisplayName);
      slTableOne.Add(FieldTypeToString(query_ex.Fields[i].DataType));
      slTableOne.Add(IntToStr(query_ex.Fields[i].Size));
      Inc(i);
      query_ex.Next;
    end;
Wie komme ich jetzt noch an den Schlüssel ran?

(Und vielleicht noch nebenbei. Gibt es eine Möglichkeit TFieldType in String umzuwandeln? Ich musste mir dafür jetz ne eigene Funktion schreiben, aber ich bin sicher dass das auch anders geht. :))


Vielen Dank für eure Hilfe

Franz

nahpets 9. Feb 2010 10:20

Re: TADOQuery Primary Key auslesen
 
Hallo,

schau Dir für den Index doch mal query_ex.indexfields an.

Ducksoul 9. Feb 2010 10:51

Re: TADOQuery Primary Key auslesen
 
Delphi-Quellcode:
if query_ex.IndexFieldCount <> 0 then
begin
  slTableOne.Add(query_ex.IndexFields[0].AsString);
  ShowMessage('Hallo');
end;
Müsste nicht, wenn ich diesen Code in der Schleife einfüge, zumindest mal eine Msg mit 'Hallo' aufloppen? Sonst würde es doch bedeuten, dass es keine Indexfelder gibt?

Also ich muss zugeben, dass mir die Delphihilfe bei diesem Thema irgendwie gar nicht hilft. :-/

hoika 9. Feb 2010 11:06

Re: TADOQuery Primary Key auslesen
 
Hallo,

dann nimm halt Google ;)

Lösung.
ADO unterstützt IndexFieldCount nicht für Access.

Guggst du hier
1

Suche dort nach IndexFieldCount.
Dort steht auch ein möglicher Workaround (IndexDef).

Einen anderen hatte ich vor kurzem gepostet.
Suche mal nach MetaData Access (in Google).


Heiko

Ducksoul 10. Feb 2010 11:19

Re: TADOQuery Primary Key auslesen
 
So ich hab jetzt mal den Workaround probiert. Allerdings stelle ich mir jetzt noch die Frage was da genau passiert.

Delphi-Quellcode:
        ADODataSet1.CommandText := 'SELECT * From Kunde';
        ADODataSet1.Active := True;
      if ADODataSet1.IndexName <> '' then
        begin
          ADODataSet1.IndexDefs.Update;
          IndexDef := ADODataSet1.IndexDefs.Find(ADODataSet1.IndexName);
          if IndexDef <> nil then
            FList := IndexDef.Fields else
            FList := '';
        end;
        ShowMessage(FList);
Er springt gar nich in die if-Schleife rein. Allerdings kann ich auch nicht so ganz nachvollziehen was IndexName eigentlich ist. Wie muss ich das jetzt noch anpassen, dass mir auch der Primärschlüssel ausgegeben wird?

Gruß

hoika 10. Feb 2010 12:15

Re: TADOQuery Primary Key auslesen
 
Hallo,

Aus Google.

Zitat:

Using DAO you can look through the TableDef.Indexes collection. There is
an Index.Primary property that is true if the index is a primary key
index. You can then find the field names by looking at the fields
collection of the Index. There may be a more direct way using DAO that I
am not aware of.
Also

Delphi-Quellcode:
ADODataSet1.CommandText := 'SELECT * From Kunde';
        ADODataSet1.Active := True;
        ADODataSet1.IndexDefs.Update;

        for i:= 0 to ADODataSet1.IndexDefs.Count-1 do
        begin
          IndexDef:= ADODataSet1.IndexDefs[i]
          if IndexDef.Primary ...


Heiko

Ducksoul 10. Feb 2010 13:00

Re: TADOQuery Primary Key auslesen
 
Hey,

das was dort beschrieben wurde behandelt DAO Komponenten. Das Ding ist nun allerdings, dass die Software grade komplett von DAO auf ADO umgestellt wird.

IndexDef besitzt bei ADO also leider keine Property namens 'Primary'.

Ich habe jetzt meinen Code wie folgt geändert:
Delphi-Quellcode:
        ADODataSet1.CommandText := 'SELECT * From Kunde';
        ADODataSet1.IndexName := 'Kundenschluessel';
        ADODataSet1.Active := True;
        ...
Ich komm mit dem Begriff index und Indexname dummerweise nicht klar, was wohl auch der Grund ist warum ich die Hilfe so schlecht verstehe *g*

Was muss da bei Indexname hin? Der Spaltenname oder 'Primary' oder was?
Inzwischen fühl ich mich genötigt mich für meine Begriffsstutzigkeit zu entschuldigen: Sry ^^

hoika 10. Feb 2010 13:48

Re: TADOQuery Primary Key auslesen
 
Hallo,

Indexname wird eigentlich nur von den TXTable benutzt.
Bei einer Query macht das keinen Sinn.


Heiko

hoika 10. Feb 2010 13:52

Re: TADOQuery Primary Key auslesen
 
Hallo,

noch ein Tip

TADOConnection.OpenSchema

TSchemaInfo = (siAsserts, ... siForeignKeys, siPrimaryKeys,

1

Es kann sein, dass die CursorLocation (clUseServer, clUseClient) noch eine Rolle spielt

-> Ausprobieren


Heiko

Ducksoul 11. Feb 2010 11:36

Re: TADOQuery Primary Key auslesen
 
Hallo,

deine Hilfe hat mich schon um einiges weitergebracht.
Inzwischen habe ich folgende zwei Funktionen:

Delphi-Quellcode:
function Timport_form.RetrievePrimaryKeys : String;
var
  Filter: OLEVariant;
  DS: TADODataSet;
  i: Integer;
begin
  result := '';
  Filter := VarArrayCreate([0, 2], varVariant);
  Filter[2] := 'Stammdata'; // Tabellenname der zu prüfenden Tabelle

  try
    DS := TADODataSet.Create(nil);
    DS.Connection := adocon_ex;
    adocon_ex.OpenSchema(siPrimaryKeys, Filter, EmptyParam, DS);
    DS.Active := True;

    with DS do
      for i := 0 to Pred(Fields.Count) do
      begin
          if (Fields[i].DisplayName = 'COLUMN_NAME')
          and (Fields[i].DisplayText <> '') then
          result := '#' + Fields[i].DisplayText; // übergibt PrimaryKey
      end;
  finally
    DS.Free;
  end;
end;

Delphi-Quellcode:
function Timport_form.RetrieveForeignKeys : String;
var
  Filter: OLEVariant;
  DS: TADODataSet;
  i: Integer;
begin
  result := '';
  Filter := VarArrayCreate([0, 2], varVariant);
  Filter[2] := 'Stammdata'; // Tabellenname der zu prüfenden Tabelle

  try
    DS := TADODataSet.Create(nil);
    DS.Connection := adocon_ex;
    adocon_ex.OpenSchema(siForeignKeys, Filter, EmptyParam, DS);
    DS.Active := True;

    with DS do
      for i := 0 to Pred(Fields.Count) do
      begin
          if (Fields[i].DisplayName = 'PK_COLUMN_NAME')
          and (Fields[i].DisplayText <> '') then
            result := '#' + Fields[i].DisplayText + ', '; // übergibt PrimaryKey, falls gleichzeit FK
          if (Fields[i].DisplayName = 'FK_TABLE_NAME')
          and (Fields[i].DisplayText <> '') then
            result := result + Fields[i].DisplayText + ', '; // übergibt Tabellennamen FK
          if (Fields[i].DisplayName = 'FK_COLUMN_NAME')
          and (Fields[i].DisplayText <> '') then
            result := result + Fields[i].DisplayText + ', '; // übergibt Spalte FK
          end;
      result := Copy(result, 0, Length(result)-2);
  finally
    DS.Free;
  end;
end;

Ich hoffe dass das jetzt alles soweit klappt.

Gruß

hoika 11. Feb 2010 12:33

Re: TADOQuery Primary Key auslesen
 
Hallo,

du setzt try finally irgendwie nicht richtig ein.

Delphi-Quellcode:
function Timport_form.RetrievePrimaryKeys : String;
var
  Filter: OLEVariant;
  DS: TADODataSet;
  i: Integer;
begin
  result := '';
  Filter := VarArrayCreate([0, 2], varVariant);
  Filter[2] := 'Stammdata'; // Tabellenname der zu prüfenden Tabelle

  DS := TADODataSet.Create(nil);
  try
    DS.Connection := adocon_ex;
    adocon_ex.OpenSchema(siPrimaryKeys, Filter, EmptyParam, DS);
    DS.Active := True;

    with DS do
      for i := 0 to Pred(Fields.Count) do
      begin
          if (Fields[i].DisplayName = 'COLUMN_NAME')
          and (Fields[i].DisplayText <> '') then
          result := '#' + Fields[i].DisplayText; // übergibt PrimaryKey
      end;
  finally
    DS.Free;
  end;
end;

Heiko

Ducksoul 11. Feb 2010 14:18

Re: TADOQuery Primary Key auslesen
 
Ja das war ein kleiner Denkfehler, welcher schon behoben ist.

Danke trotzdem :)

Ducksoul 15. Feb 2010 13:32

Re: TADOQuery Primary Key auslesen
 
Hallo,
ich möchte nochmal eine überarbeitete Version der Funktionen einstellen, da oben genannte nicht zu 100% funktioniert haben.

Delphi-Quellcode:
(* Primärschlüssel auslesen                                                  *)
function Timport_form.GetPrimaryKeys : String;
var
  Filter: OLEVariant;
  DS: TADODataSet;
  Field: TField;
begin
  result := '';
  Filter := VarArrayOf([NULL, NULL, Table]);
  DS := TADODataSet.Create(nil);
  try
    DS.Connection := dbcon;
    dbcon.OpenSchema(siPrimaryKeys, Filter, EmptyParam, DS);

    Field := DS.FindField('COLUMN_NAME');
    DS.First;

    while not DS.EOF do
    begin
      result := result + '#' + Field.AsString + ', ';
      DS.Next;
    end;
    result := Copy(result, 0, Length(result)-2);
  finally
    DS.Free;
  end;
end;

Delphi-Quellcode:
(* Fremdschlüssel auslesen                                                   *)
function Timport_form.GetForeignKeys : String;
var
  Filter: OLEVariant;
  DS: TADODataSet;
  fTable1, fTable2, fColumn1, fFKName: TField;
  i: integer;
begin
  result := '';
  DS := TADODataSet.Create(nil);

  try
    DS.Connection := dbcon;
    dbcon.OpenSchema(siForeignKeys , EmptyParam, EmptyParam, DS);
    fTable1 := DS.FindField('PK_TABLE_NAME');
    fColumn1 := DS.FindField('PK_COLUMN_NAME');
    fTable2 := DS.FindField('FK_TABLE_NAME');
    fFKName := DS.FindField('FK_NAME');

    DS.First;
    while not DS.Eof do
    begin
      if SameText(fTable1.AsString, Table) then
      begin
        result := result + '~' + fFKName.AsString + ', ' +
          fColumn1.AsString + ', ' + fTable2.AsString + ', ';
      end;
      DS.Next;
    end;
      result := Copy(result, 0, Length(result)-2);
  finally
    DS.Free;
  end;
end;

Diese beiden Funktionen funktionieren bis auf eine Kleinigkeit ausgezeichnet: Mir werden nur die Fremdschlüssel angezeigt, von denen aus eine Beziehung referenziert wird. Durchsuche ich eine Tabelle, auf die referenziert wird, dann liefert die Funktion GetForeignKeys kein Ergebnis. Jemand ne Ahnung, wie ich auch die importierten Keys bekomme?


Gruß

hoika 15. Feb 2010 13:38

Re: TADOQuery Primary Key auslesen
 
Hallo,

Zitat:

Durchsuche ich eine Tabelle, auf die referenziert wird, dann liefert die Funktion GetForeignKeys kein Ergebnis. Jemand ne Ahnung, wie ich auch die importierten Keys bekomme
Das ist auch richtig so.

Um herauszufinden, ob und wie eine Tabelle referenziert ist,
musst du wohl oder übel alle Foreign Keys durchlaufen
und nach der Zieltabelle suchen.


Heiko

Ducksoul 15. Feb 2010 14:07

Re: TADOQuery Primary Key auslesen
 
Ah Mensch... Das artet ja in Arbeit aus.

Danke

hoika 15. Feb 2010 15:37

Re: TADOQuery Primary Key auslesen
 
Hallo,

ist eine klitzekleine Schleife,
den Rest macht doch der Computer ... ;)


Heiko

Reibi 21. Mär 2010 15:00

Re: TADOQuery Primary Key auslesen
 
Hallo Ducksoul,

vielen Dank für deine Funktion.
An der Sache mit dem 'Primary Key' beiße ich mir schon seit Tagen die Zähne aus.

Nur, warum benutzt Du eine Schleife um das DS auszulesen?

Code:
    DS.First;

    while not DS.EOF do
    begin
      result := result + '#' + Field.AsString + ', ';
      DS.Next;
    end;
    result := Copy(result, 0, Length(result)-2);
Pro Tabelle (MS-SQL 2005) kann es doch nur einen Primary Key geben oder liege ich da falsch?

DeddyH 21. Mär 2010 15:09

Re: TADOQuery Primary Key auslesen
 
Ein PK kann aber aus mehreren Feldern zusammengesetzt sein.


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