verwendetes Datenbanksystem: <mysql 5.0.51a>
Hallo zusammen,
folgender Sachverhalt (Code weiter unten):
Ich frage mit einem einem MySQLDataReader Daten ab und lese sie danach mit der klassischen while(reader.Read())-Schleife ein. Es wird aber grundsätzlich die ERSTE Zeile der Ergebnismenge unterschlagen.
Das Problem kann nicht in der Schleife liegen, denn hasRows() ist false, wenn die Ergebnismenge nur eine Zeile hat.
Woher ich weiß, dass die Ergebnisse eine Zeile mehr haben müssten? Ganz einfach: Ich prüfe das (garantiert gleiche) Statement im SQL-Developer gegen und habe eine Zeile mehr (also eine, wenn die Ergebnismenge in meinem Programm keine hat, zwei, wenns in meinem Programm eine ist etc. etc.)
Beispielstatements:
select a.ArtID, a.Name, a.Description, a.ArtGrpID, g.Name as ArtGrpName,a.FormatID, a.Width, a.Height, a.IsPrintfun, a.TSCreated, a.TSChanged, a.LabType from cw_new_article a left join cw_new_articlegroup g on a.artgrpid=g.artgrpid where a.artid='8328';
liefert im SQL-Developer eine Zeile als Ergebnismenge (hasRows () in c# gibt mir false zurück):
8328 sticker_05 PHOTOPRODUCT 18 premiumphoto 0 52 60 0 2010-11-11 12:35:17.0 2010-11-15 17:28:16.0 30
Die folgende Abfrage gibt im SQL-Developer 14 Zeilen zurück, c# gibt mir nur 13 und unterschlägt die erste:
select a.ArtID, a.Name, a.Description, a.ArtGrpID, g.Name as ArtGrpName,a.FormatID, a.Width, a.Height, a.IsPrintfun, a.TSCreated, a.TSChanged, a.LabType from cw_new_article a left join cw_new_articlegroup g on a.artgrpid=g.artgrpid where a.artid like '%83';
So zieht sich das durch alle Abfragen, unabhängig davon, welche Tables und Operatoren in verwende... Die Ergebnismenge in c# unterschlägt grundsätzlich die erste Zeile und hat damit eine weniger, als es sein sollte....
Hier nun der Code dazu:
connection.Open();
MySqlDataReader Reader = command.ExecuteReader();
List<string[]> resultset = new List<string[]>();
while (Reader.Read())
{
List<string> row = new List<string>();
for (int i = 0; i < Reader.FieldCount; i++)
{
string value = Reader.GetValue(i).ToString();
if (value.Length == 0) value = "N/A";
row.Add(value);
}
resultset.Add(row.ToArray());
}
Anmerkung: Die aufwändigen Strukturen mit den Listen lassen sich leider nicht vermeiden, weil ich die Methode universell einsetze und die Dimension der Ergebnistabelle vorher nicht feststeht.
Ich selbst suche nun seit zwei Tagen und kann kein Problem entdecken... Wäre also super, wenn jemand etwas dazu sagt, der Ahnung hat 😄
Danke im Voraus,
Ho conator,
den wichtigen Teil hast Du leider ausgelassen, denn der Fehler wird durch das SQL-Statement und die (vielleicht) verwendeten Parameter entstehen.
MfG
wax
Hi Wax!
Recht hast Du! 😃 Ich habe nun mal beispielhaft zwei Statements mit Ergebnis in den Beitrag gebaut. Wobei sich das durch alle Statements zieht - unabhängig von verwendeten Tables, Operatoren, Operanden etc... MySQLDatareader gibt immer exakt eine Zeile weniger, als es sein sollte :-\
Ich tippe auf den OUTER JOIN....
edit: ups, ist ja garkein OUTER JOIN. Das LEFT hat mich verwirrt. 😃
Ich tippe auf den OUTER JOIN....
Aber das Statement an sich kann's doch nicht sein, wenn's im SQL-Developer die korrekte Ergebnismenge liefert? Lediglich in C# wird eine Zeile zu wenig geliefert... Evtl. habe ich die Antwort aber auch nicht verstanden?
Tritt das Problem denn auch auf wenn Du ein Query ohne JOIN absetzt?
Ich hatte so etwas auch schonmal bei unserer GUPTA DB. Das Problem war entweder ein nicht gesetzter Parameter im Command-Objekt oder eben eine Verkettung von OUTER JOIN´s die ich hatte und die bei mir auch im GUPTA-ManagementStudio ein anderes Ergebnis geliefert hatten als per .NET-Provider.
MfG
wax
Ich habe das nun mal ohne JOIN versucht. Es wird noch immer eine Zeile unterschlagen. Aber evtl. waren die Parameter des Command-Objektes ein guter Tipp. Ich werde mal gucken, was da so gesetzt werden kann und berichte, sollte da die Lösung sein...
Für Dein Feedback schon mal danke! 😃
Hi,
ich meinte nicht irgendeinen Parameter, sondern einen "IDbDataParameter" den du vielleicht vergessen hast zu zuweisen.
Doch das wird bei dir wohl nicht der Fall sein, da du in deinem ersten Query ja die ID hat codiert hattest und das Problem trotzdem aufgetreten ist. Also ich bin dann mit meinem Latein am Ende.
MfG
wax
Hrm... sogar bei Minimal-SELECTs immer eine Zeile weniger. Ich werd' bescheuert 😃
Danke Dir trotzdem für die Mühe!!
Hallo!
Ich kenne mich mit dem DataReader nicht aus, aber kann es evtl. sein, dass die while-Schleife umgedreht werden müsste, d.h. das erste Ergebnis bereits vom Reader vorgehalten wird.
Alternativ kannst du ja mal alles nicht über einen Reader sondern direkt als DataTable abrufen und vergleichen.
Nobody is perfect. I'm sad, i'm not nobody 🙁
Hi,
hat vllt der Mysql-Treiber ein bug? Andere Version verwenden? MysqlTreiber-Source in das Projekt einbinden und mit debuggen?
Ich kenne mich mit dem DataReader nicht aus, aber kann es evtl. sein, dass die while-Schleife umgedreht werden müsste, d.h. das erste Ergebnis bereits vom Reader vorgehalten wird.
Alternativ kannst du ja mal alles nicht über einen Reader sondern direkt als DataTable abrufen und vergleichen. Das erklärt die DataReader.HasRows-Problematik nicht.
@tom-essen:
Das dachte ich auch zuerst. Meistens liegt der Fehler ja auch da. Aber wie witte schon schreibt... Die Ergebnismenge ist wirklich kleiner. Das beweist unter Anderem der Check mit .hasRows() bei (eigentlich) einzeiligen Ergebnismengen.
Inzwischen habe ich auch welche, bei denen noch mehr Zeilen fehlen. Habe da schon nach Gemeinsamkeiten in den fehlenden / gemeinsam enthaltenen Zeilen gesucht, finde aber nichts...
witte: Ich checke nun mal andere MySQL-Treiber checken :-\
Danke schon einmal für Eure Mühe! 😃
Anmerkung: Die aufwändigen Strukturen mit den Listen lassen sich leider nicht vermeiden, weil ich die Methode universell einsetze und die Dimension der Ergebnistabelle vorher nicht feststeht.
Sorry, aber das ist Blödsinn.
Wenn du eine universelle Routine haben willst, benutze einen DataAdapter und eine DataTable.
Da lässt sich dann auch ausschliessen das es am Datenholen selber liegt.
Hallo!
Ich tippe mal einfach auf die Verarbeitung der unterschiedlichen Treiber im Bezug auf where a.artid='8328'
Da du das ja als "String" übergibst könnte es da sein, dass dein mysql Treiber diesen anders verarbeitet als das Management Studio?
Versuch mal eine Testtabelle mit nem Zahlenwert.
Ich tippe mal darauf, dass manche deiner Zeilen mit Blanks aufgefüllt werden, und du dadurch where a.artid='8328%' schreiben musst.
Wobei natürchlich where RTRIM(a.artid)='8328' die schönere Variante wäre.
Hallo,
es gibt (oder gab) einen Bug im mySql-DataReader
http://stackoverflow.com/questions/3350153/mysqldatareader-stops-reading-after-about-4-minutes-and-returns
Und zwar meldet der Datareader, er habe alle Zeilen gelesen, allerdings ist er beim Lesen irgendwo ausgestiegen und die dabei ausgelöste Exception wird sang und klanglos verschluckt.
Ein sehr ähnliches Problem hatte ich vor einiger Zeit auch auf einer nie optimierten MySql-Datenbank, nachdem extrem viele Deletes und Inserts ausgeführt wurden. Da gab es dann mit dem DataReader ganz komische Ergebnisse, es kam quasi überhaupt nichts richtiges mehr zurück. Ich habe die Datenbank dann weggeschmissen (das ging, war eine Testdatenbank 😃)
und eine neue genommen. Danach funktionierte alles wieder reibungslos.
Grüße
Christian
@FZelle: Hast' Recht. Problematik bleibt aber bestehen 🙂
@Tomleech: Klang super, hat aber leider nicht geholfen. Wäre zu schön gewesen 😁
@Chriscolm: Danke für den Link. Habe ich in der Form selbst durch intensives Googlen nicht finden können. Scheint aber darauf hinauszulaufen, dass es einen Bug im McSqlConnector gibt und er im Ggs zu anderen Schnittstellen MySQL-DB nicht immer fehlerfrei abfragen kann (und gemeinerweise die Exception unterschlägt).
Ich werde ich da mal durcharbeiten...
Danke und Gruß an alle 😁
Übrigens unterschlägt der MySQLDataAdapter ebenfalls Zeilen (zum Teil knapp die Hälfte). Das Problem muss also defintiv in der MySQLConnection-Klasse liegen...
Das Problem tritt sogar auf, wenn man einen extra angelegten Table mit einer Spalte und wenig Daten abfragt... Strange...
Ich habe das Problem lösen können:
Mit einem alternativen Connector werden die Daten vollständig ausgelesen. Vermutlich also wirklich ein Bug im herkömmlichen MySqlConnector aus dem Hause MySql.
Den alternativen Connector gibt es hier
Die Express-Variante ist übrigens kostenlos 😁
Vielleicht hilft's ja mal dem einen oder anderen, der auf die gleiche Problematik stößt... 🙂