Hi, Ich weiß nicht, ob dies eher in den VB.NET Bereich gehört oder in den SQL-Server Bereich, aber da cross-postings nicht gehen, stelle ich das mal in eines, und hoffe dass man mir Bescheid gibt, sollte man es verschieben
Also zum Problem:
Beim Updaten einer Datenbank suche ich mir zunächst alle Datensätze, die einer bestimmten Bedingung entsprechen, Öffne dann einen SQLDataReader und gehe in einer Schleife Datensatz für Datensatz durch um entsprechende Felder zu setzen und eventuelle Fehler zu protokollieren, damit diese notfalls manuell nachgezogen weden können. Die Schleifendurchläufe zähle ich in einer Double (brauche ich für den Fortschrittsbalken in frm), die Felder setze ich durch einen DataWriter, der im Prinzip nichts anderes ist als eine Kapselung der Sammlung eines "UPDATE <Tabellenname> SET .. WHERE <DatensatzID>=..." Statements und dw.Update führt dann seinerseits sqlExecute für das Statement aus, der SqlDataReader wird von der Klasse clsdataReader gekapselt, die dann auch per Item(fldName) erhaltene Werte je nach Aufruffunktion in Strings, Doubles, Dates oder Integer umwandelt.
[highlight=vbnet]
...
Dim count As Integer
Dim c as Double = 0.0
count = session.db.sqlGetLng("SELECT Count(*) FROM KonfBezBedingungen" & session.db.WithNoLock & " WHERE NOT(Bedingung IS NULL)")
If count > 0 And session.db.FieldType("KonfBezBedingungen", "Bedingung") = clsDatabase.DBFieldType.DBText Then
frm.showinfo("Wandele KonfBezBedingungen...", 0)
session.db.AddField("KonfBezBedingungen", "BackupLangtext", "MEMO")
session.db.sqlExecute("UPDATE KonfBezBedingungen" & session.db.WithRowLock & " SET BackupLangtext=NULL")
s = "UPDATE KonfBezBedingungen" & session.db.WithRowLock & " SET BackupLangtext=Bedingung WHERE NOT(Bedingung IS NULL)"
session.db.sqlExecute(s)
session.db.DelField("KonfBezBedingungen", "Bedingung")
session.db.AddField("KonfBezBedingungen", "Bedingung", "TEXT(4000)")
c = 0.0
dr.OpenReadonly(session.db, "SELECT * FROM KonfBezBedingungen" & session.db.WithNoLock & " WHERE NOT(BackupLangtext IS NULL)")
While dr.Read() And Not frm.Abbrechen
Dim BedID As Integer = dr.getLng("KonfBezBedingungID")
Try
frm.showinfo("", c * 100.0 / CType(count, Double))
dw.OpenEdit(session.db, "KonfBezBedingungen", "KonfBezBedingungID", BedID)
s = dr.getStr("BackupLangtext")
dw.SetFieldValue("Bedingung", s)
dw.Update()
Catch
errlog.OpenLogFile("X:\Transfer\DietzM\NText2NVarc har.log")
errlog.WriteLine(StrDup(80, "_"c), False)
errlog.WriteLine("Für die KonfBezBedingung " & BedID & " konnte die Bedingung nicht übernommen werden. ", False)
errlog.WriteLine(s, False)
errlog.WriteLine(StrDup(80, "_"c), False)
errlog.CloseLogFile()
Finally
If Not (dw Is Nothing) Then dw.Close()
End Try
c += 1.0
End While
dr.Close()
session.db.DelField("KonfBezBedingungen", "BackupLangtext")
End If
...
[/highlight]
Wenn ich diese Schleife aber im Debugger durchgehe, habe ich das Phänomen dass z.B. count =4084 ist, aber c=5217.0 oder aber (noch schlimmer) count ist 5547, c aber 5534.0, und es bleiben eine Menge unbearbeitete Datensätze zurück, was in diesem Fall fatal ist, da ich die Spalte danach im Glauben ich hätte alles korrekt zurückgeschrieben, entferne.
Können diese Probleme irgendwie damit zusammenhängen, dass ich den eben gerade gelesenen Datensatz beschreibe, bevor ich zum nächsten gehe? Da ich aber das Feld in der WHERE-Klausel nicht anfasse, sollte es doch eigentlich nichts ausmachen. Oder liegt das Problem darin, dass ich das im Debug-Modus durchlaufe, und der SQLDataReader deshalb Blödsinn macht? Hat der SqlDataReader an sich irgendwelche Macken, die dieses Problem verursachen?
Ich hoffe jemand kann mir helfen, ich habe nämlich keine Ahnung wo da der Wurm drinhängt. Gut, für das aktuelle Problem mag es möglich sein, die betroffenen Datensätze in eine andere Tabelle zu speichern, um den gleichzeitigen Zugriff auf denselben Datensatz zu vermeiden, wenn man sich aber so Szenarien ansieht, wie einen Abgleich aller Datensätze die als "frei" markiert sind, ob sie immer noch frei sind (was dann die Bedingung der Abfrage verändert) oder eine Iteration über alle Datensätze um z.B. Status-IDs umzusetzen, da kann es schon fatal sein, wenn man ein SQL-Statement wegen möglicher Probleme nicht nutzen kann, andererseits dem DataReader aber auch nicht trauen darf..
Mit freundlichen Grüßen
Martin Dietz
Also zum Problem:
Beim Updaten einer Datenbank suche ich mir zunächst alle Datensätze, die einer bestimmten Bedingung entsprechen, Öffne dann einen SQLDataReader und gehe in einer Schleife Datensatz für Datensatz durch um entsprechende Felder zu setzen und eventuelle Fehler zu protokollieren, damit diese notfalls manuell nachgezogen weden können. Die Schleifendurchläufe zähle ich in einer Double (brauche ich für den Fortschrittsbalken in frm), die Felder setze ich durch einen DataWriter, der im Prinzip nichts anderes ist als eine Kapselung der Sammlung eines "UPDATE <Tabellenname> SET .. WHERE <DatensatzID>=..." Statements und dw.Update führt dann seinerseits sqlExecute für das Statement aus, der SqlDataReader wird von der Klasse clsdataReader gekapselt, die dann auch per Item(fldName) erhaltene Werte je nach Aufruffunktion in Strings, Doubles, Dates oder Integer umwandelt.
[highlight=vbnet]
...
Dim count As Integer
Dim c as Double = 0.0
count = session.db.sqlGetLng("SELECT Count(*) FROM KonfBezBedingungen" & session.db.WithNoLock & " WHERE NOT(Bedingung IS NULL)")
If count > 0 And session.db.FieldType("KonfBezBedingungen", "Bedingung") = clsDatabase.DBFieldType.DBText Then
frm.showinfo("Wandele KonfBezBedingungen...", 0)
session.db.AddField("KonfBezBedingungen", "BackupLangtext", "MEMO")
session.db.sqlExecute("UPDATE KonfBezBedingungen" & session.db.WithRowLock & " SET BackupLangtext=NULL")
s = "UPDATE KonfBezBedingungen" & session.db.WithRowLock & " SET BackupLangtext=Bedingung WHERE NOT(Bedingung IS NULL)"
session.db.sqlExecute(s)
session.db.DelField("KonfBezBedingungen", "Bedingung")
session.db.AddField("KonfBezBedingungen", "Bedingung", "TEXT(4000)")
c = 0.0
dr.OpenReadonly(session.db, "SELECT * FROM KonfBezBedingungen" & session.db.WithNoLock & " WHERE NOT(BackupLangtext IS NULL)")
While dr.Read() And Not frm.Abbrechen
Dim BedID As Integer = dr.getLng("KonfBezBedingungID")
Try
frm.showinfo("", c * 100.0 / CType(count, Double))
dw.OpenEdit(session.db, "KonfBezBedingungen", "KonfBezBedingungID", BedID)
s = dr.getStr("BackupLangtext")
dw.SetFieldValue("Bedingung", s)
dw.Update()
Catch
errlog.OpenLogFile("X:\Transfer\DietzM\NText2NVarc har.log")
errlog.WriteLine(StrDup(80, "_"c), False)
errlog.WriteLine("Für die KonfBezBedingung " & BedID & " konnte die Bedingung nicht übernommen werden. ", False)
errlog.WriteLine(s, False)
errlog.WriteLine(StrDup(80, "_"c), False)
errlog.CloseLogFile()
Finally
If Not (dw Is Nothing) Then dw.Close()
End Try
c += 1.0
End While
dr.Close()
session.db.DelField("KonfBezBedingungen", "BackupLangtext")
End If
...
[/highlight]
Wenn ich diese Schleife aber im Debugger durchgehe, habe ich das Phänomen dass z.B. count =4084 ist, aber c=5217.0 oder aber (noch schlimmer) count ist 5547, c aber 5534.0, und es bleiben eine Menge unbearbeitete Datensätze zurück, was in diesem Fall fatal ist, da ich die Spalte danach im Glauben ich hätte alles korrekt zurückgeschrieben, entferne.
Können diese Probleme irgendwie damit zusammenhängen, dass ich den eben gerade gelesenen Datensatz beschreibe, bevor ich zum nächsten gehe? Da ich aber das Feld in der WHERE-Klausel nicht anfasse, sollte es doch eigentlich nichts ausmachen. Oder liegt das Problem darin, dass ich das im Debug-Modus durchlaufe, und der SQLDataReader deshalb Blödsinn macht? Hat der SqlDataReader an sich irgendwelche Macken, die dieses Problem verursachen?
Ich hoffe jemand kann mir helfen, ich habe nämlich keine Ahnung wo da der Wurm drinhängt. Gut, für das aktuelle Problem mag es möglich sein, die betroffenen Datensätze in eine andere Tabelle zu speichern, um den gleichzeitigen Zugriff auf denselben Datensatz zu vermeiden, wenn man sich aber so Szenarien ansieht, wie einen Abgleich aller Datensätze die als "frei" markiert sind, ob sie immer noch frei sind (was dann die Bedingung der Abfrage verändert) oder eine Iteration über alle Datensätze um z.B. Status-IDs umzusetzen, da kann es schon fatal sein, wenn man ein SQL-Statement wegen möglicher Probleme nicht nutzen kann, andererseits dem DataReader aber auch nicht trauen darf..
Mit freundlichen Grüßen
Martin Dietz
Comment