Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Access Datenbank mit ADODataSet (https://www.delphipraxis.net/175137-access-datenbank-mit-adodataset.html)

MechMac666 1. Jun 2013 13:06

Datenbank: MS Access • Version: 12 • Zugriff über: ADODataSet

Access Datenbank mit ADODataSet
 
Hallo,

ich verwende eine Access Datenbank und greife mit ADODataSet darauf zu.
Zum Filtern verwende ich SQL.

Die Datenbank hat 2 Tabellen.

Wenn ich nun

Code:
  form1.ADODataSet1.Insert;
  form1.ADODataSet1.Edit;
  [..]
  form1.ADODataSet1.post;
verwende, woher weiß ich und vor allem ADODataSet in welcher Tabelle der neue Datensatz gespeichert werden soll?

Ich hatte schon mal probiert mit
'SELECT * FROM BILDER'
bzw.
'SELECT * FROM ARTEN'
nur die Einträge einer Tabelle zu bekommen,
in der Hoffnung das dann auf diese Tabelle der letzten Abfrage gezeigt wird und
dort auch dann der neue Eintrag erstellt wird.
Aber das scheint nicht so ganz zu funktionieren.

Der schöne Günther 1. Jun 2013 13:15

AW: Access Datenbank mit ADODataSet
 
Ich kenne mich mit Datenbanken nicht aus, habe aber vor ein paar Wochen auch einmal kurz schnell etwas für Access mit den ADO-Komponenten zusammengezimmert.

Ich kann nur sagen, dass ich drei Komponenten hatte, in dieser Reihenfolge aufeinander aufbauend:


TDataSource->(ADOTable|AdoQuery|…?)->ADOConnection:<Jet, OLE DB, ODBC>

TDataSet ist eine implementierende Unterklasse von TDataSource, oder? Somit müsste das Teil doch entweder an einem ADOTable- oder ADOQuery-Objekt dranhängen?

MechMac666 1. Jun 2013 13:20

AW: Access Datenbank mit ADODataSet
 
Also die Datenbankverbindung an sich klappt wunderbar. Auch die SQL-Abfragen funktionieren.

Das einzigste "Problem" was ich habe, ist das mir nicht klar ist, woher "das System" weiß, in welcher Tabelle ich den neuen Datensatz erstellt haben möchte.

DataSource -> ADODataSet ->DBGrid etc.

Rainer Wolff 1. Jun 2013 13:40

AW: Access Datenbank mit ADODataSet
 
Ich habe nie mit dem ADODataset gearbeitet, sondern nur mit ADOTable/ADOQuery, daher kenne ich die Komponente auch nicht. Aber ich zietiere mal aus der Delphi-Hilfe:

Die Datenmenge wird mit Hilfe der Eigenschaft CommandText des TADODataSet-Objekts abgerufen. Weisen Sie dieser Eigenschaft den betreffenden Tabellennamen oder eine SQL-Anweisung (nur SELECT) zu. Mit der Datenmengenkomponente können nur DML-SQL-Anweisungen (Data Manipulation Language) ausgeführt werden, die eine Ergebnismenge zurückliefern. Für SQL-Anweisungen wie DELETE, INSERT und UPDATE sind Komponenten wie TADOCommand oder TADOQuery besser geeignet.

Demnach also für Insert nicht zu empfehlen

Gruß Rainer

blondervolker 1. Jun 2013 13:48

AW: Access Datenbank mit ADODataSet
 
Liste der Anhänge anzeigen (Anzahl: 1)
ADOConnection
DataSource
ADOTable

Leg noch ein Datenmodul an und klatsche da alles drauf.
Dann lege eine oder mehrere Forms an und schreibe in Uses Datamodul oder
wie das Ding auch immer heissen soll.

Dann klatsche eine Tabelle auf eine Form und schau dann im Objektinspektor
was für eine Tabelle oder Table usw. zugewiesen werden soll.

Siehe Abb.1

Bernhard Geyer 1. Jun 2013 14:17

AW: Access Datenbank mit ADODataSet
 
Wenn was in Access trotz keiner Fehler nicht sichtbar ist liegt das am bescheuerten Caching-Verhalten von Access.

Im Entwickler-Forum gabs mal Beispielcode wie man die Jet-Engine zwingen kann ohne jedesmal die Verbindung zu beenden den Cache zu leeren..
Leider finde ich den Beitrag nicht mehr. War von Andreas Kosch.

MechMac666 1. Jun 2013 14:57

AW: Access Datenbank mit ADODataSet
 
Ähm? Nicht sichtbar?

Also wenn ich einen neuen Datensatz erzeuge ist der schon sichtbar, er ist nur nicht in der Tabelle wo ich ihn gerne hätte.
Ich verbinde das ADODataset mit einer Datenbank. Im Connectionstring steht nix von einer Tabelle o.ä. Da lege ich nur fest welche Datenbank.
Wenn ich nun ne Abfrage mache, ist es mittels SQL ja kein Problem diese Abfrage über mehrere Tabellen laufen zu lassen.

Und nun gehe ich her und erstelle einen neuen Datensatz.

ADODataSet1.Insert; <--Toll, "insert"..Und wo? Er weiß doch gar nicht in welcher Tabelle er das einfügen soll.

Im Notfall kann man ja auch mittels SQL nen Datensatz erzeugen. Das werde ich dann wohl auch machen müssen, wenn es mit den Delphi Hausmitteln vom Zufall abhängig ist, wo meine Daten landen.
Aber erstmal abwarten, vielleicht meldet sich ja noch jemand der das Problem schon mal hatte :-D

Volker Z. 1. Jun 2013 16:36

AW: Access Datenbank mit ADODataSet
 
Hallo,

Zitat:

Im Notfall kann man ja auch mittels SQL nen Datensatz erzeugen. Das werde ich dann wohl auch machen müssen, wenn es mit den Delphi Hausmitteln vom Zufall abhängig ist, wo meine Daten landen.
Es hängt nicht vom Zufall ab. Ließ Dir mal die OH zu dem Thema durch.
TADODataSet verwenden
TADODataSet

Dann wirst Du über die Eigenschaften CommandText und CommandType stolpern. Mit:
Delphi-Quellcode:
ADODataSet1.CommandText := 'Tablename'; // z. B. 'BILDER'
ADODataSet1.CommandType := cmdTable; // bzw. cmdTableDirect
ADODataSet1.Insert;
ADODataSet1.FieldByName ('Fieldname').AsString := 'Fieldvalue';
[...]
ADODataSet1.Post
sollte einen Datensatz in die Tabelle schreiben. (Nicht getestet)

Aber wie hier und in der OH schon erwähnt ist für ein INSERT TADOCommand besser geeignet.

Gruß

Bernhard Geyer 1. Jun 2013 17:19

AW: Access Datenbank mit ADODataSet
 
Poste doch mal ein abgespecktes Beispiel hier

Perlsau 1. Jun 2013 19:25

AW: Access Datenbank mit ADODataSet
 
Zitat:

Zitat von MechMac666 (Beitrag 1217187)
... woher weiß ich und vor allem ADODataSet in welcher Tabelle der neue Datensatz gespeichert werden soll?

Ist im Grunde alles ziemlich einfach: Du hast erst einmal eine AdoConnection, die du entsprechend einrichtest, damit die richtige Datenbank angesprochen wird. Dann nimmst du dir ein Dataset dazu und weist dessen Connection-Property deine AdoConnection zu. Um nun die richtige Tabelle auszuwählen, klickst du auf die drei Punkte im Property CommandText. Es erscheint ein selbsterklärendes Dialogfenster, in dessen oberer Combobox du die Tabelle auswählst und in der unteren Combobox die anzuzeigenden Felder. Deine Auswahl wird automatisch zu einem SQL-String zusammengebaut. Es wird nun immer die eingetragene Tabelle angesprochen.

Erzeugst du ein Dataset zur Laufzeit, um z.B. neue Datensätze anzulegen, gehst du analog vor:
Delphi-Quellcode:
function TDatMod.Waren_NeuerDatensatz(Art_Nr, Anzahl, Lieferant: Integer; Farbe : String): Boolean;
Var
   AsetNeu : TAdoDataset;

begin
   Result := False;
   AsetNeu := TAdoDataset.Create(DatMod);
   Try
      AsetNeu.Connection := ADOCon;
      AsetNeu.CommandText := 'select * from WarenTabelle';
      AsetNeu.Active := True;
      AsetNeu.Append; // oder AsetNeu.Insert;
      AsetNeu.FieldByName('ArtikelNr').AsInteger := Art_Nr;
      AsetNeu.FieldByName('Anzahl').AsInteger := Anzahl;
      AsetNeu.FieldByName('Lieferant').AsInteger := Lieferant;
      AsetNeu.FieldByName('Farbe').AsString := Farbe;
      AsetNeu.Post;
      Result := True;
   Finally
      FreeAndNil(AsetNeu);
   End;
end;
Oder wenn du mit einem Query und SQL arbeiten willst:
Delphi-Quellcode:
function TDatMod.Waren_NeuerDatensatz(Art_Nr, Anzahl, Lieferant: Integer; Farbe : String): Boolean;
Const
   K = ',';  // Komma
   Ka = '('; // KlammerAuf
   Kz = ')'; // KlammerZu

Var
   AQuery : TAdoQuery;

begin
   Result := False;
   AQuery := TAdoDataset.Create(DatMod);
   Try
      AQuery.Connection := ADOCon;
      AQuery.SQL.Append('insert into WarenTabelle');
      AQuery.SQL.Append(Ka + 'ArtikelNr, Anzahl, Lieferant, Farbe' + Kz);
      AQuery.SQL.Append('values');
      AQuery.SQL.Append(Ka + IntTostr(Art_Nr) + K + IntToStr(Anzahl) + K + IntToStr(Lieferant) + K + QuotedStr(Farbe) + Kz);
      AQuery.ExecSQL;
      Result := True;
   Finally
      FreeAndNil(AsetNeu);
   End;
end;
Du siehst hier am Aufbau der beiden Funktionen im Grunde alles, was dazu nötig ist, neue Datensätze einzufügen.

MechMac666 1. Jun 2013 20:14

AW: Access Datenbank mit ADODataSet
 
In diesem Zusammenhang würde mich interessieren ob ich gleichzeitig mit zwei ADODataSet's auf eine DB zugreifen kann, oder gibt das kuddelmuddel?

Perlsau 1. Jun 2013 20:18

AW: Access Datenbank mit ADODataSet
 
Zitat:

Zitat von MechMac666 (Beitrag 1217220)
In diesem Zusammenhang würde mich interessieren ob ich gleichzeitig mit zwei ADODataSet's auf eine DB zugreifen kann, oder gibt das kuddelmuddel?

Datasets greifen in der Regel nicht auf Datenbanken (DBs) zu, sondern lediglich auf die Datenbank-Connection.
Da eine DB gewöhnlich mehr als eine Tabelle enthält, sind meist auch mehrere Datasets notwendig, um diese Tabellen in der Anwendung bearbeiten zu können.

Kann es vielleicht sein, daß hier eine Verwechslung vorliegt und du eigentlich fragen wolltest, ob es Probleme geben kann, wenn mehrere Datasets auf dieselbe Tabelle zugreifen?

MechMac666 1. Jun 2013 20:37

AW: Access Datenbank mit ADODataSet
 
Hm, ich habe direkt mit dem Dataset die Verbindung mit der Datenbank aufgebaut (ConnectionString).
Meine Datenbank hat mehrere Tabellen und die Abfragen gehen über mehrere Tabellen.
Das mache ich mit SQL.
Also mit dem CommandText.

Nun muss ich aber zwei DBgrids mit verschieden Daten (Abfragen) aus einer Datenbank versorgen.
(Es ist möglich das diese Abfragen über mehrere Tabellen gehen)


Könnte ich jetzt mit einem zweiten Dataset die selbe Datenbank nochmal
verbinden und damit eine Abfrage machen, oder ggf. auch einen neuen Datensatz erstellen?


Ps.: MUSS ich denn die Datenbank-Connection eigentlich nutzen?
Was ist der Vorteil?

Perlsau 1. Jun 2013 20:49

AW: Access Datenbank mit ADODataSet
 
MS-Access stellt keine Multiuser-Datenbank dar. Daher ist es sinnvoll, mit nur einer DB-Connection zu arbeiten. Zu diesem Zweck gibt es TAdoConnection. Über das Verhalten bei direkter Verbindung mehrerer Datasets zu ein und derselben Datenbank kann ich dir nichts weiter sagen, da ich dieses Szenario noch nicht ausprobiert hatte und auch nicht vorhabe, das zu tun. Jedoch habe ich Erfahrung mit dem Zugriff auf eine Access-DB durch mehrere Client-Anwendungen. Greifen gleichzeitig mehrere Clients auf dieselbe Tabelle oder gar denselben Datensatz dar, kann es zu Problemen kommen, weil Access die in Bearbeitung befindlichen Datensätze nicht für weiteren Zugriff sperrt. Das können nur Multiuser-DBMS. Access ist aber als reine Desktop-DB nur für den Single-User-Einsatz konzipiert.

Du solltest dir daher die insbesondere bei anderen DBMS übliche Vorgehensweise angewöhnen und eine Connection-Komponente einsetzen, über die du deine Datasets und Queries verbindest. Der Vorteil liegt u.a. darin, daß du nicht bei jedem Zugriff auf eine Tabelle eine neue Datenbank-Verbindung herstellen mußt.

MechMac666 1. Jun 2013 21:04

AW: Access Datenbank mit ADODataSet
 
Danke für die ausführliche Erklärung.

Das heißt also, ich erstelle eine ADOConnection und kann mit mehreren Datasets darauf zugreifen. (Ich muss nicht erst eine davon deaktivieren)
Und diese Datasets können aber alle mit gleichen und/oder unterschiedlichen CommandType verbunden werden und mittels CommandText SQL-Abfragen machen?

Oder als Beispiel:

Das erste Dataset macht folgende Abfrage mit CommandType=CMDTEXT und stellt es in DBGrid1 dar.
CommandText:='SELECT Bilder.Art, Bilder.Pfad, Bilder.Fundort, Bilder.Funddatum, Bilder.EXIF, Arten.Vorkommen, Arten.Familie, Arten.Unterfamilie, Arten.Gattung, Arten.Tagfalter, Arten.Nachtfalter, Arten.[Artname Alternativ], Bilder.ID
FROM Bilder INNER JOIN Arten ON Bilder.Art = Arten.Artname';

Das zweite Dataset macht folgende Abfrage mit CommandType=CMDTABLE und stellt es in DBGrid2 dar.
CommandText:='BILDER';


Wenn das klappen würde, wäre es eine riesige Hilfe für mich da ich das momentan auf umständlichste Art und Weise mache... :(

Perlsau 1. Jun 2013 21:09

AW: Access Datenbank mit ADODataSet
 
Probiere es doch einfach aus! Übrigens stellt der String 'BILDER' keinen SQL-Befehl dar und muß daher bei Zuweisung an das Property CommandText zu einer Fehlermeldung führen. Des weiteren empfehle ich dir dringend, die Online-Hilfe zu den Ado-Komponenten (dbGo) zu studieren. Dort findest du alle relevanten Informationen.

Statt komplexer Select-Befehle kannst du in den Datasets auch Lookup-Felder erstellen. Wie das geht, steht ebenfalls in der OH.

MechMac666 1. Jun 2013 21:32

AW: Access Datenbank mit ADODataSet
 
Da ich es unbedingt direkt testen wollte habe ich bereits ein Ergebnis.
Auf den ersten Blick scheint es zu funktionieren.
Habe bei dem kurzen Test zumindest keine Probleme damit entdecken können.


Dass das 'BILDER' kein SQL-Befehl ist, ist mir klar, ich habe es in einem Post weiter oben gelesen.
Zitat:
ADODataSet1.CommandText := 'Tablename'; // z. B. 'BILDER'
ADODataSet1.CommandType := cmdTable; // bzw. cmdTableDirect


Ich hätte es wie folgt, jedoch im Modus CMDTEXT ausgedrückt:
SELECT * FROM BILDER
Nur es ging doch darum, das ich das dataset auf eine spezielle Tabelle lenke.
Ob SELECT * FROM BILDER im Modus CMDTABLE funktioniert, habe ich nicht getestet.

Wie auch immer, jetzt muss ich erstmal grundlegend einiges umstricken und die AdoConnection sowie weitere Datasets einbauen.

Volker Z. 2. Jun 2013 00:51

AW: Access Datenbank mit ADODataSet
 
Hallo,

Zitat:

Dass das 'BILDER' kein SQL-Befehl ist, ist mir klar, ich habe es in einem Post weiter oben gelesen.
Scheinbar aber die Links dazu übersehen. Ließ Dir doch mal die Dokumentation dazu durch.

Zitat:

Ob SELECT * FROM BILDER im Modus CMDTABLE funktioniert, habe ich nicht getestet.
Ist nicht nötig, funktioniert sicher nicht.
Delphi-Quellcode:
CommandType := cmdTable
erwartet in der Eigenschaft CommandText einen Tabellennamen und nichts anderes.

Wenn Du alle Datensätze einer Tabelle (hier BILDER) anzeigen möchtest (TDataSource an die entsprechende Komponente gebunden):
Delphi-Quellcode:
ADODataSet1.Connection := ADOConnection1;
ADODataSet1.CommandText := 'BILDER';
ADODataSet1.CommandType := cmdTable;
ADODataSet1.Open;
oder
Delphi-Quellcode:
ADODataSet1.Connection := ADOConnection1;
ADODataSet1.CommandText := 'SELECT * FROM BILDER';
ADODataSet1.CommandType := cmdText;
ADODataSet1.Open;
oder
Delphi-Quellcode:
ADOTable1.Connection := ADOConnection1;
ADOTable1.Tablename := 'BILDER';
ADOTable1.Open;
oder
Delphi-Quellcode:
ADOQuery1.Connection := ADOConnection1;
ADOQuery1.SQL.Text  := 'SELECT * FROM BILDER';
ADOQuery1.Open;
liefert Dir identische Ergebnisse. Such es Dir aus, welche Variante Dir gefällt.

Wenn Du einen Datensatz in eine Tabelle (hier Arten) einfügen möchtest, dann:
Delphi-Quellcode:
ADOCommand1.Connection := ADOConnection1;
ADOCommand1.CommandText := 'INSERT INTO Arten(Vorkommen, Familie, Unterfamilie, Gattung, Tagfalter, Nachtfalter) VALUES([...])';
ADOCommand1.Execute;
oder
Delphi-Quellcode:
ADODataSet1.Connection := ADOConnection1;
ADODataSet1.CommandText := 'Arten';
ADODataSet1.CommandType := cmdTable;
ADODataSet1.Insert; // oder ADODataSet1.Append;
ADODataSet1.FieldByName ('Vorkommen').AsString := '[...]';
[...]
ADODataSet1.FieldByName ('Nachtfalter').AsString := '[...]';
ADODataSet1.Post
oder
Delphi-Quellcode:
ADOQuery1.Connection := ADOConnection1;
ADOQuery1.SQL.Text := 'INSERT INTO Arten(Vorkommen, Familie, Unterfamilie, Gattung, Tagfalter, Nachtfalter) VALUES([...])';
ADOCommand1.ExeSQL;
oder
Delphi-Quellcode:
ADOTable1.Connection := ADOConnection1;
ADOTable1.Tablename  := 'Arten';
ADOTable1.Open;
ADOTable1.Insert; // oder ADOTable1.Append;
ADOTable1.FieldByName ('Vorkommen').AsString := '[...]';
[...]
ADOTable1.FieldByName ('Nachtfalter').AsString := '[...]';
ADOTable1.Post
legt Dir einen neun Datensatz in der Tabelle an. Such es Dir aus, welche Variante Dir gefällt.

Zitat:

Wie auch immer, jetzt muss ich erstmal grundlegend einiges umstricken und die AdoConnection sowie weitere Datasets einbauen.
Da ist eigentlich nichts grundlegendens zu ändern! Nur die ADOConntcion entsprechend initialisieren und entsprechend an die Komponente binden. That' s all!

Wenn Du ein Join über mehrere Tabellen fahren möchtest, dann TADODataset oder TADOQuery.

Nur: Mir ist nur noch immer nicht klar wo denn Dein Problem nun eigentlich liegt.

Gruß

MechMac666 2. Jun 2013 14:45

AW: Access Datenbank mit ADODataSet
 
Zitat:

Da ist eigentlich nichts grundlegendens zu ändern! Nur die ADOConntcion entsprechend initialisieren und entsprechend an die Komponente binden. That' s all!
Naja, da ich das mit den mehreren DBGrids bei nur einem Dataset vorher sehr umständlich gemacht habe, waren da schon noch diverse "Altlasten" die ich entfernen bzw. anpassen musste.


Zitat:

Nur: Mir ist nur noch immer nicht klar wo denn Dein Problem nun eigentlich liegt.
Seit meinem letzten Post, habe ich eigentlich kein Problem mehr,
da das mit der AdoConnection und den mehreren Datasets supi funktioniert. :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz