Laden...

SqlDataAdapter und Update()

Erstellt von Sharpovski vor 18 Jahren Letzter Beitrag vor 18 Jahren 4.769 Views
S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren
SqlDataAdapter und Update()

Ich habe folgendes Problem. Mit einem SqlDataAdapter werden mit der Update Methode Daten aus einem DataSet mit der Datenbank abgeglichen. Nun bekomme ich hin und wieder eine SqlException, dass der Timeout abgelaufen ist. Wie kann ich herausfinden, bei welchem Command genau das Problem auftritt?

178 Beiträge seit 2006
vor 18 Jahren

Moin,

der StackTrace sollte Dir helfen...
Weiterhin der SQL Profiler...

Enjoy

Christian Arnold

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Das Problem trat bei einem internen DELETE auf. Eine Erhöhung von CommandTimeout konnte bereits helfen.

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Wie kann ich herausfinden, wieso gerade die DELETE-Anweisung so lange dauert?

178 Beiträge seit 2006
vor 18 Jahren

Moin,

bitte poste mal Deine Delete-Anweisung...

Enjoy

Christian Arnold

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Es gibt keine spezielle DELETE-Anweisung. Ich hole mir ein DataSet aus der Datenbank. Füge entweder Zeilen hinzu oder aktualisiere diese und rufe schließlich die Update-Methode aus.

178 Beiträge seit 2006
vor 18 Jahren

Also nutzt du einen commandbuilder?

Enjoy

Christian Arnold

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Also ich befülle mit "SELECT * FROM tabelle WHERE id = irgendeineZahl" über die Fill-Methode des SqlDataAdapters ein DataSet. Nach einigen Überprüfungen kann es jetzt vorkommen, dass ich eine Zeile lösche und später wieder komplett neu hinzufüge. Dann führe ich die Update-Methode des SqlDataAdapters aus.

178 Beiträge seit 2006
vor 18 Jahren

Hmm,

also irgendwie musst Du ja dem Adapter einen Delete Befehl geben.
Entweder nutzt Du einen manuellen oder einen CommandBuilder.

Zunächst:

NIEMALS "Select *" verwenden!

Nutzt Du denn nun einen CommandBuilder?

Enjoy

Christian Arnold

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Achso, einen CommandBuilder verwende ich nicht. Die DELETE-Anweisung wird dadurch erzeugt, dass ich die Zeile aus dem DataSet herauslösche. Wenn ich nun die Update-Methode des SqlDataAdapters aufrufe, wird hier intern ein DELETE ausgeführt.

E
265 Beiträge seit 2004
vor 18 Jahren

Hallo phunkydizco

Verwendest du den SqlDataAdapter Wizard (Configure DataAdapter/Konfiguriere DatenAdapter)?
Wenn ja, dann verwendest du einen CommandBuilder. Ansonsten nicht. (Dann musst du die INSERT, UPDATE, DELETE Commands selbst erstellen.)

Eine möglichkeite wäre (timeout wieder auf den default wert setzen), try/catch um die Update methode. Im catch ein dataSet.dataTable.GetErrors() aufrufen und nachsehen welche Row(s) einen Error verursacht haben. Eventuell steht in der Fehler beschreibung was genaueres drinnen als "timeout occured".

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Hab jetzt nochmal genau nachgesehen und ich verwende doch einen CommandBuilder. Den SqlDataAdapter Wizard verwende ich allerdings nicht.

Das mit dem GetErrors ist eine gute Idee. Gibt es eine Möglichkeit die Anweisung bei der der Fehler aufgetreten ist dann nochmal mit einem höheren Timeout zu wiederholen, ohne die Update-Methode mit einer Exception zu verlassen?

178 Beiträge seit 2006
vor 18 Jahren

Moin,

dann bilde Dir Dein Delete selber. CommandBuilder ist nicht wirklich gut!
Und wie gesagt, zu liebe des Ablaufplans NIEMALS "SELECT *" verwenden!

Bilde Dir selbst Deine Abfragen (INSERT UPDATE DELETE) und vergiss in jedem Fall den CommandBuilder... Vermutlich ist Dein Problem dann vergessen....
Der Builder erzeugt nicht gerade optimale Abfragen / Statements

Enjoy

Christian Arnold

E
265 Beiträge seit 2004
vor 18 Jahren

ContinueUpdateOnError beim DatenAdapter auf true stellen und nach dem Update befehl überprüfen ob Fehler aufgetreten sind (GetErrors).
Danach TimeOut erhöhen und versuchen nochmal zu updaten. Aufpassen das es in keiner endlos schleife endet.

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Ob es wirklich sinnvoll ist den Update-Methode bei einem Fehler weitermachen zu lassen und dass dann nochmals mit einem höheren Timeout zu wiederholen. Könnten da nicht unterumständen in der Daten doppelte bzw. fehlerhafte Datensätze erzeugt werden.

E
265 Beiträge seit 2004
vor 18 Jahren

Die frage ob es sinnvoll ist musst du selbst beantwortet, du hast gefragt ob es geht. Meine antwort ja 🙂

Wenn du eine Exception bei einer INSERT Anweisung bekommst, liegt es daran das es nicht funktioniert hat -> doppelte Datensätze sind also "unmöglich".
Das gleiche bei UPDATE, DELETE.

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Wäre es vielleicht möglich die DELETE-Anweisung innerhalb des DataAdapters zu überschreiben?

Ich lösche bestimmte Zeilen anhand von Überprüfungen aus dem DataSet mittels DataRow.Delete() und führe danach die Update()-Methode des DataAdapters aus. Wie könnte ich hier die DELETE-Anweisung überschreiben?

178 Beiträge seit 2006
vor 18 Jahren

Moin,

also überschrieben wird hier nichts...

Wie ich oben bereits mehrfach erwähnt habe ->

ersetzte den CommandBuilder durch eigene Commands!

Nur so hast Du eine vernünftige Basis.

Enjoy

Christian Arnold

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Wie funktioniert das denn mit dem DataAdapter ohne CommandBuilder? Kann ich dann trotzdem im DataSet die Zeilen selber einfügen und löschen und dann die Update()-Methode verwenden?

178 Beiträge seit 2006
vor 18 Jahren

Enjoy

Christian Arnold

E
265 Beiträge seit 2004
vor 18 Jahren

Original von phunkydizco
Kann ich dann trotzdem im DataSet die Zeilen selber einfügen und löschen und dann die Update()-Methode verwenden?

Ja.

Der DataAdapter macht folgendes.
Er läuft das DataSet row by row durch und überprüft den RowState. Ist der RowState "Added" wird ein INSERT ausgeführt, "Modified" -> UPDATE, "Deleted" -> DELETE.

Wie diese 3 Befehle erzeugt werden, CommandBuilder oder manuell, ist egal. Sie sollten funktionieren ^^
Ich musste die Commands noch nie selbst schreiben, daher weis ich nicht genau wie die ausehen, bezüglich primary key und parameter.

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Genau das ist mein Problem. Wie funktioniert das mit den Parametern, wenn ich mehere Zeilen lösche?

B
483 Beiträge seit 2005
vor 18 Jahren

Parameter haben mit löschen mehreren Zeilen nicht zu tun.

178 Beiträge seit 2006
vor 18 Jahren

Original von phunkydizco
Genau das ist mein Problem. Wie funktioniert das mit den Parametern, wenn ich mehere Zeilen lösche?

Hast Du dir das Dokument überhaubt angesehen?

Als Tip:

Besorge Dir das Buch

http://www.amazon.de/exec/obidos/ASIN/3827262291/qid=1140605568/sr=8-2/ref=sr_8_xs_ap_i2_xgl/028-9320049-3430123

Enjoy

Christian Arnold

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Habe jetzt die DELETE-Anweisung folgendermaßen überschrieben.

dataAdapter.DeleteCommand = new SqlCommand("DELETE FROM tabelle WHERE Id = @Id");
dataAdapter.DeleteCommand.Parameters.Add("@Id", SqlDbType.Int, 9, "Id");

Wird sich in den nächsten Tagen zeigen, ob sich das TimeOut-Problem damit beheben lässt. Den CommandBuilder werde ich für die anderen Anweisungen wohl erstmal weiter verwenden.

178 Beiträge seit 2006
vor 18 Jahren

CommandBuilder wirklich NUR wenn absolut einfache Anweisungen auszuführen sind UND Performance absolut KEINE Rolle spielt.

Enjoy

Christian Arnold

S
Sharpovski Themenstarter:in
259 Beiträge seit 2004
vor 18 Jahren

Bei meinem CommandBuilder wird nur ein Select/Update anhand einer ID gemacht. Also keine Joins oder sonstiges. Ich denke damit sollte es keine Probleme geben. Werde mir jetzt allerdings die Zeiten der einzelnen Anweisungen mal genauer anschauen und bei Bedarf den CommandBuilder ausbauen.