Discussion:
Datenbank mit einem DataAdapter aktualisieren
(zu alt für eine Antwort)
Dominik Sauer
2009-05-14 12:39:46 UTC
Permalink
Hallo NG,

ich möchte meine geänderten Daten aus dem Dataset (enthält 2 Tabellen)
in der Datenbank aktualisieren.
Leider bekomme ich das nicht hin.

Ich habe es auf zwei Arten probiert:

1. Ich wollte die Daten manuell durch das Commandobjekt mit dem
jeweiligen Befehl (Insert, Update, Delete) in der Datenbank
aktualisieren.
Dies funktioniert leider nicht bei gelöschten DataRows. Diese sind
zwar im DataTable nur als zu löschen markiert , jedoch kann man nicht
mehr auf die Spalteninhalte zugreifen um die Where-Klause des SQL-
Strings zu erstellen.

2. Habe ich es über das CommandBuilderobjekt versucht (2. Wahl).
Da ich aber in meinem DataSet 2 Tabellen gespeichert habe ist der
CommandBuilder damit überfordert.
Nach viel lesen habe ich jetzt 2 DataAdabter (für jede Tabelle einen)
und 2 CommandBuilder.
Beim Aufruf des ersten DataAdapter.Update() kommt eine Fehlermeldung.
("Spalte '[Spalte aus Tabelle2]' gehört nicht zu Tabelle [Tabelle1].")


Vielleicht hat mir jemand helfen?!


MfG Dominik
Peter Fleischer
2009-05-14 15:05:44 UTC
Permalink
1. Ich wollte die Daten manuell durch das Commandobjekt mit dem jeweiligen
Befehl (Insert, Update, Delete) in der Datenbank aktualisieren. Dies
funktioniert leider nicht bei gelöschten DataRows. Diese sind zwar im
DataTable nur als zu löschen markiert , jedoch kann man nicht mehr auf die
Spalteninhalte zugreifen um die Where-Klause des SQL-Strings zu erstellen.
Hi Dominik,
wenn du auf die OriginalVersion zugreifst, dann hast du in den gelöschten
DataRows die ursprpnglichen Werte.
2. Habe ich es über das CommandBuilderobjekt versucht (2. Wahl). Da ich
aber in meinem DataSet 2 Tabellen gespeichert habe ist der CommandBuilder
damit überfordert. Nach viel lesen habe ich jetzt 2 DataAdabter (für jede
Tabelle einen) und 2 CommandBuilder. Beim Aufruf des ersten
DataAdapter.Update() kommt eine Fehlermeldung. ("Spalte '[Spalte aus
Tabelle2]' gehört nicht zu Tabelle [Tabelle1].")
2 Tabellen im DataSet erfordern 2 DataAdapter mit jeweils einem
CommandBuilder. Du kannst aber nur die passenden Spalten aktualisieren.
--
Viele Grüsse
Peter
Peter Götz
2009-05-15 06:09:13 UTC
Permalink
Hallo Dominik,
Post by Dominik Sauer
ich möchte meine geänderten Daten aus dem
Dataset (enthält 2 Tabellen) in der Datenbank
aktualisieren.
Leider bekomme ich das nicht hin.
1. Ich wollte die Daten manuell durch das Commandobjekt
mit dem jeweiligen Befehl (Insert, Update, Delete) in der
Datenbank aktualisieren.
Ein Beispiel hierfür findest Du unter

www.gssg.de -> Visual Basic -> VB.net
-> DB CommandObjekte / DataReader

Bei diesem Beispiel werden die Daten über einen
DataReader in eine DataTable eingelesen und können
dort bearbeitet werden. Der Abgleich mit der Datenbank
erfolgt ohne DataAdapter direkt mit den entsprechenden
Command-Objekten.
Post by Dominik Sauer
Dies funktioniert leider nicht bei gelöschten DataRows.
Diese sind zwar im DataTable nur als zu löschen markiert,
jedoch kann man nicht mehr auf die Spalteninhalte
zugreifen um die Where-Klause des SQL-
Strings zu erstellen.
Schau Dir das o.g. Beispiel an, darin können auch DS
gelöscht werden.
Post by Dominik Sauer
2. Habe ich es über das CommandBuilderobjekt versucht (2. Wahl).
Ein Beispiel zum Bearbeiten einer DB-Tabelle mit Hilfe eines
DataAdapters und eines CommandBuilders findest Du unter

www.gssg.de -> Visual Basic -> VB.net
-> OLEDB2 (Access.mdb)

Das Beispiel arbeitet mit einer Access.mdb. Das dort
gezeigte Prinzip zum Bearbeiten von DS (hinzufügen,
ändern, löschen) ist aber genauso für einen SQL-Server
anwendbar. Lediglich der Verbindungsaufbau zur DB
(erstellen des Connectionobjektes) wäre dann anders
und wird in den Beispielen unter

www.gssg.de -> Visual Basic -> VB.net
-> SQLserver_00, SQLserver_01, SQLserver_02

gezeigt.
Post by Dominik Sauer
Da ich aber in meinem DataSet 2 Tabellen gespeichert
habe ist der CommandBuilder damit überfordert.
Nach viel lesen habe ich jetzt 2 DataAdabter (für jede
Tabelle einen) und 2 CommandBuilder.
s.oben:
Du brauchst für jede DataTable einen eigenen DataAdapter.
Post by Dominik Sauer
Beim Aufruf des ersten DataAdapter.Update() kommt eine
Fehlermeldung.
("Spalte '[Spalte aus Tabelle2]' gehört nicht zu
Tabelle [Tabelle1].")
Ohne Deinen relevanten Code zu kennen, kann ich das
nicht kommentieren.
Post by Dominik Sauer
Vielleicht hat mir jemand helfen?!
Die o.g. Beispiele sollten Klarheit bringen.

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Dominik Sauer
2009-05-15 09:20:52 UTC
Permalink
Hallo Peter,
hallo Peter,

vielen Dank für die Antworten.

@ Peter Fleischer:
Wie kann ich auf die Originalversion zugreifen?

@ Peter Götz:
In deinem Beispiel "DB CommandObjekte / DataReader" sendest du den
Delete-Command direkt beim löschen der DataRow.
Hab ich das richtig verstanden?

Nun ist es bei mir leider so, dass ich erst nachdem der Nutzer mehrere
Änderungen im Dataset gemacht hat die Daten an den Server schicke.
1. um Abbrechen zu realisieren und 2. um den Traffic im Netz so gering
wie möglich zu halten.

Hier ist der mein Code zum CommandBuilder,
vielleicht findet Ihr den Fehler.

private MySqlDataAdapter myadapterpe =
new MySqlDataAdapter();
private MySqlDataAdapter myadapterpue =
new MySqlDataAdapter();
private DataSet myds = new DataSet();

mycommand.CommandText=
"Select * " +
"From Tab1;";
myadapterpe.SelectCommand = mycommand;
myadapterpe.TableMappings.Add("Table", "Tab1");
myadapterpe.Fill(myds);

mycommand.CommandText=
"Select * From Tab2 " +
"Order by Spalte2;";
myadapterpue.SelectCommand = mycommand;
myadapterpue.TableMappings.Add("Table", "Tab2");
myadapterpue.Fill(myds);

...Daten werden editiert, gelöscht oder neu eingetragen

MySqlCommandBuilder mybuilderpe =
new MySqlCommandBuilder(myadapterpe);
MySqlCommandBuilder mybuilderpue =
new MySqlCommandBuilder(myadapterpue);

myadapterpe.InsertCommand = mybuilderpe.GetInsertCommand();
myadapterpe.UpdateCommand = mybuilderpe.GetUpdateCommand();
myadapterpe.DeleteCommand = mybuilderpe.GetDeleteCommand();

myadapterpue.InsertCommand = mybuilderpue.GetInsertCommand();
myadapterpue.UpdateCommand = mybuilderpue.GetUpdateCommand();
myadapterpue.DeleteCommand = mybuilderpue.GetDeleteCommand();

myconn.Open();
myadapterpe.Update(myds); // --> hier kommt die die oben beschriebene
Fehlermeldung
myadapterpue.Update(myds);
myconn.Close();


MfG Dominik
Dominik Sauer
2009-05-15 10:45:14 UTC
Permalink
Hallo,

ich habe das CommandBuilder-Problem gelöst.
Post by Dominik Sauer
private MySqlDataAdapter myadapterpe =
new MySqlDataAdapter();
private MySqlDataAdapter myadapterpue =
new MySqlDataAdapter();
private DataSet myds = new DataSet();
Irgendwie kommen die DataAdapter nicht damit zurecht, dass sie
Klassenvariablen sind.
Man muss also beim "Befüllen" des DataSets 2 Adapter erstellen
und auch beim "Updaten" der Datenbank.


MfG Dominik
Peter Götz
2009-05-15 12:16:28 UTC
Permalink
Hallo Dominik,

In deinem Beispiel "DB CommandObjekte / DataReader"
sendest du den Delete-Command direkt beim löschen
der DataRow.
Hab ich das richtig verstanden?
Ja, das Beispiel soll auch nur zeigen, wie DB-Zugriffe
ohne DataAdapter direkt mit entspr. Commandobjekten
ablaufen.
Nun ist es bei mir leider so, dass ich erst nachdem der
Nutzer mehrere Änderungen im Dataset gemacht hat die
Daten an den Server schicke.
1. um Abbrechen zu realisieren und 2. um den Traffic im
Netz so gering wie möglich zu halten.
Schau Dir dazu das Beispiel

www.gssg.de -> Visual Basic -> VB.net
-> DataTable / DataView , RowState

an. Darin siehst Du, wie Du an hinzugefügte, geänderte
und auch als gelöscht gekennzeichnete Datensätze in
einer DataTable kommst. Damit hast Du ein Mittel an
der Hand, erst alle Hinzufügungen, Änderungen und
Löschungen an Deiner DataTable zu machen und dann
die betr. Datensätze mit der eigentlichen DB-Tabelle
via entspr. CommandObjekt abzugleichen.
Hier ist der mein Code zum CommandBuilder,
vielleicht findet Ihr den Fehler.
private MySqlDataAdapter myadapterpe =
new MySqlDataAdapter();
private MySqlDataAdapter myadapterpue =
new MySqlDataAdapter();
private DataSet myds = new DataSet();
Da Dein DataSet offensichtlich nur zwei DataTables,
jedoch keine RelationObjekte enthält, ist ein DataSet
überflüssiger Ballast. Die DataTables können auch
ohne umhüllendes DataSet erstellt und bearbeitet
werden.
mycommand.CommandText=
"Select * " +
"From Tab1;";
myadapterpe.SelectCommand = mycommand;
myadapterpe.TableMappings.Add("Table", "Tab1");
myadapterpe.Fill(myds);
mycommand.CommandText=
"Select * From Tab2 " +
"Order by Spalte2;";
myadapterpue.SelectCommand = mycommand;
myadapterpue.TableMappings.Add("Table", "Tab2");
myadapterpue.Fill(myds);
...Daten werden editiert, gelöscht oder neu eingetragen
MySqlCommandBuilder mybuilderpe =
new MySqlCommandBuilder(myadapterpe);
MySqlCommandBuilder mybuilderpue =
new MySqlCommandBuilder(myadapterpue);
myadapterpe.InsertCommand = mybuilderpe.GetInsertCommand();
myadapterpe.UpdateCommand = mybuilderpe.GetUpdateCommand();
myadapterpe.DeleteCommand = mybuilderpe.GetDeleteCommand();
myadapterpue.InsertCommand = mybuilderpue.GetInsertCommand();
myadapterpue.UpdateCommand = mybuilderpue.GetUpdateCommand();
myadapterpue.DeleteCommand = mybuilderpue.GetDeleteCommand();
Das mit dem DataAdapter und dem CommandBuilder ist offensichtlich
noch nicht so ganz klar geworden.

Dim DA as ...DataAdapter = _
new ...DataAdapter(SqlString, Connection)

Dim CB = New ...CommandBuilder(DA)
With CB
.ConflictOption = gewünschte ConfliktOption
.QuotePrefix = "["
.QuoteSuffix = "]"
.SetAllValues = True/False
End With

Das wars auch schon. Also keine einzelne Zuweisung
von Insert-, Update- u. DeleteCommand. Das machen
DataAdapter und CommandBuilder untereinander
zum richtigen Zeitpunkt aus.

Schau Dir dazu nochmal das Beispiel unter

www.gssg.de -> Visual Basic -> VB.net
OLEDB2 (Access.mdb)

an. IM Klassenmodul clsDbIO.vb gibt es eine unter-
geordnete Klasse clsTableAdapter und in deren
Sub New siehst Du das Erstellen des DataAdapters,
des zugehörigen CommandBuilders und wie die
beiden miteinander verbunden werden.

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Dominik Sauer
2009-05-15 13:41:17 UTC
Permalink
Hallo Peter,

danke für die Antwort.
Post by Peter Götz
Die DataTables können auch
ohne umhüllendes DataSet erstellt und bearbeitet
werden.
Wie kann ich die Daten ohne DataSet in die DataTables laden?
In meiner Literatur wird immer ein DataSet dazu verwendet.
Post by Peter Götz
Das mit dem DataAdapter und dem CommandBuilder ist offensichtlich
noch nicht so ganz klar geworden.
...
Das wars auch schon. Also keine einzelne Zuweisung
von Insert-, Update- u. DeleteCommand. Das machen
DataAdapter und CommandBuilder untereinander
zum richtigen Zeitpunkt aus.
Die Zuweisungen waren reine Verzweiflungstaten, da ich nicht
weiterkam.

Habe den Fehler ja bereits gefunden (s. o.).


Vielen Dank für deine Hilfe.


MfG Dominik
Peter Götz
2009-05-15 16:23:11 UTC
Permalink
Hallo Dominik,
Post by Dominik Sauer
Post by Peter Götz
Die DataTables können auch
ohne umhüllendes DataSet erstellt und bearbeitet
werden.
Wie kann ich die Daten ohne DataSet in die DataTables laden?
Na ja, ich habe Dich doch schon mehrmals auf
die Beispiele unter

www.gssg.de -> Visual Basic -> VB.net
-> OLEDB2 (Access.mdb
und
-> DB CommandObjekte / DataReader

hingewiesen. In beiden siehst Du, wie man Daten in
eine DataTable bringt, ohne dass es dazu ein DataSet
gibt. Ansehen musst Du diese Beispiele schon selbst.
Post by Dominik Sauer
In meiner Literatur wird immer ein DataSet dazu verwendet.
Ein DataSet ist erst mal nichts weiter als ein Behälter
für andere Objekte. Das können auch DataTables und
RelationObjekte sein, welche solche DataTables zu-
einander in Beziehung setzen. In so einem Fall ist
ein DataSet erforderlich. Hast Du lediglich eine oder
mehrere DataTables, die nicht via RelationObjekt mit-
einander in Beziehung stehen, dann ist auch kein
DataSet notwendig.
Aber wie schon erwähnt, schau Dir halt die Beispiele
an, dann siehst Du, dass DataTables sowohl über einen
DataReader als auch einen DataAdapter mit Daten
gefüllt werden können, ohne dass diese DataTables
in einem DataSet liegen.
Post by Dominik Sauer
Post by Peter Götz
Das mit dem DataAdapter und dem CommandBuilder
ist offensichtlich noch nicht so ganz klar geworden.
...
Das wars auch schon. Also keine einzelne Zuweisung
von Insert-, Update- u. DeleteCommand. Das machen
DataAdapter und CommandBuilder untereinander
zum richtigen Zeitpunkt aus.
Die Zuweisungen waren reine Verzweiflungstaten,
da ich nicht weiterkam.
Habe den Fehler ja bereits gefunden (s. o.).
Na ja, nicht wirklich und ich vermute, dass Du
noch nicht so recht verstanden hast, wie DataAdapter
und CommandBuilder zusammenarbeiten um
Datensätze einer DB-Tabelle hinzuzufügen, Datensätze
in einer DB-Tabelle zu ändern und Datensätze aus
einer DB-Tabelle zu löschen.
Aber auch hierzu nochmal der Verweis auf das Beispiel
unter

www.gssg.de -> Visual Basic -> VB.net
-> OLEDDB2 (Access.mdb)

in welchem die Verwendung eines DataAdapters
zusammen mit einem CommandBuilder gezeigt wird.
Beispiele ansehen und verstehen kann ich Dir leider
nicht abnehmen, das musst Du schon selbst tun.

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

Loading...