MySql abfragen mit Qt
MySql abfragen mit Qt
Hallo Community,
ich bin aktuell dabei ein Programm zu schreiben, dass sich zu einer Datenbank verbindet und erstmal nur Werte ausließt. Die Verbindung zur Datenbank hab ich bereits auch erfolgreich hergestellt ( Es ist eine MySQL4 - Datenbank) allerdings bekomm ich immer einen Fehler beim Abfragen von Tabellen Werten.
Der Fehler, der auf der Console erscheint lautet wie folgt:
"QSqlQuery::value: not positioned on a vaid record"
Das Pogramm stürzt dadurch allerdings nicht ab, es läuft weiter.
Ich weiß leider nicht was mein Rechner mir damit sagen will.
Der Quellcode dazu ist der folgende:
void test_query()
{
// Connect to Database
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL3");
db.setHostName("127.0.0.1");
db.setDatabaseName("dbname");
db.setUserName("dbusername");
db.setPassword("dbpassword");
db.setPort(dbport);
bool ok = db.open();
// ok hat den wert true, die Verbindung ist erfolgreich zur Datenbank
// aufgebaut.
// Zum test lasse ich alle Tabellen ausgeben die in der Datenbank sind
foreach (QString item, db.tables())
{
cout << "Tabelle: " << item.toStdString() << endl;
}
// Ausgabe der Tabellen war erfolgreich
QSqlQuery query("SELECT name FROM jos_users",db);
bool ok2 = query.exec();
// ok2 hat den Wert true, von daher gehe ich mal davon aus, dass
// die abfrage erfolreich ausgeführt wurde
cout << query.value(0).toString().toStdString() << endl;
query.finish();
db.close();
}
Wenn ich die Zeile "cout << query.value(0).toString().toStdString() << endl;" auskommentiere kommt der Fehler nicht. Aber irgendwie muss ich ja jetzt an den Wert herankommen den ich aus der Datenbank abgefragt habe. In dem Fall alle namen der Tabelle jos_users
Ich hab auch mal wie es in der Dokumentation steht folgendes versucht:
while (quey.next() )
{
cout << query.value(0).toString().toStdString() << endl;
}
statt nur die Ausgabe, allerdings stürzt das Programm dann bei query.next() ab. Vll hilft das jemandem weiter.
Danke schonmal für Lösungsideen.
Gruß
ich bin aktuell dabei ein Programm zu schreiben, dass sich zu einer Datenbank verbindet und erstmal nur Werte ausließt. Die Verbindung zur Datenbank hab ich bereits auch erfolgreich hergestellt ( Es ist eine MySQL4 - Datenbank) allerdings bekomm ich immer einen Fehler beim Abfragen von Tabellen Werten.
Der Fehler, der auf der Console erscheint lautet wie folgt:
"QSqlQuery::value: not positioned on a vaid record"
Das Pogramm stürzt dadurch allerdings nicht ab, es läuft weiter.
Ich weiß leider nicht was mein Rechner mir damit sagen will.
Der Quellcode dazu ist der folgende:
void test_query()
{
// Connect to Database
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL3");
db.setHostName("127.0.0.1");
db.setDatabaseName("dbname");
db.setUserName("dbusername");
db.setPassword("dbpassword");
db.setPort(dbport);
bool ok = db.open();
// ok hat den wert true, die Verbindung ist erfolgreich zur Datenbank
// aufgebaut.
// Zum test lasse ich alle Tabellen ausgeben die in der Datenbank sind
foreach (QString item, db.tables())
{
cout << "Tabelle: " << item.toStdString() << endl;
}
// Ausgabe der Tabellen war erfolgreich
QSqlQuery query("SELECT name FROM jos_users",db);
bool ok2 = query.exec();
// ok2 hat den Wert true, von daher gehe ich mal davon aus, dass
// die abfrage erfolreich ausgeführt wurde
cout << query.value(0).toString().toStdString() << endl;
query.finish();
db.close();
}
Wenn ich die Zeile "cout << query.value(0).toString().toStdString() << endl;" auskommentiere kommt der Fehler nicht. Aber irgendwie muss ich ja jetzt an den Wert herankommen den ich aus der Datenbank abgefragt habe. In dem Fall alle namen der Tabelle jos_users
Ich hab auch mal wie es in der Dokumentation steht folgendes versucht:
while (quey.next() )
{
cout << query.value(0).toString().toStdString() << endl;
}
statt nur die Ausgabe, allerdings stürzt das Programm dann bei query.next() ab. Vll hilft das jemandem weiter.
Danke schonmal für Lösungsideen.
Gruß
das liegt daran das der zeiger auf die Daten vor/hinter einem gültigen datensatz liegt!
das mit den query.next() ist also nötig.
Bei deiner abfrage weiß ich nicht ob name evtl ein keyword ist.... mach doch einfach tst halber mal die abfrage "select count(*) from jos_users"
oder des bsp hier aus der doc:
das mit den query.next() ist also nötig.
Bei deiner abfrage weiß ich nicht ob name evtl ein keyword ist.... mach doch einfach tst halber mal die abfrage "select count(*) from jos_users"
oder des bsp hier aus der doc:
Code: Alles auswählen
QSqlQuery q("select * from employees");
QSqlRecord rec = q.record();
qDebug() << "Number of columns: " << rec.count();
int nameCol = rec.indexOf("name"); // index of the field "name"
while (q.next())
qDebug() << q.value(nameCol).toString(); // output all namesHallo,
ich hab versucht die Vorschläge von AuE umzusetzen, jedoch ohne Erfolg.
Folgendes habe ich versucht:
Wenn ich die Abfrage mit einem * schreibe um alle Spalten abzufragen, liefert mir query.exec() den Wert fase zurück, von daher gehe ich mal davon aus dass das nicht funktioniert hat. Acuh wenn ich zb. einen Spaltennamen eingebe, den es nicht gibt liefert exec() den Wert false. Da er bei "uersname" den Wert true ausgibt, scheint er in der Taballe die Spalte ja gefunden zu haben.
Bei "Number of Columns" bekomme ich dann den Wert 1, dass heißt ja schonmal, dass die Spalte dich ich gewählt hab anscheinend gefunden wurde.
Ich bekomme es jetzt jedoch nicht hin mir die Werte ausgeben zu lassen.
gibt mir den Wert 0 zurück, und wenn ich dann:
ausführe bekomme ich wieder meine Fehlermeldung:
Ich habe leider keine Idee mehr woran es noch liegen kann. Hoffe von euch weiß noch jemand Rat..
Danke schonmal
ich hab versucht die Vorschläge von AuE umzusetzen, jedoch ohne Erfolg.
Folgendes habe ich versucht:
Code: Alles auswählen
void klasse::test_query
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL3");
db.setHostName("127.0.0.1");
db.setDatabaseName("dbname");
db.setUserName("dbusername");
db.setPassword("dppassword");
db.setPort(dbport);
QSqlQuery query("select username from jos_users");
bool ok2 = query.exec();
QSqlRecord rec = query.record();
cout << "number of columns: " << rec.count() << endl;
int nameCol = rec.indexOf("username");
cout << "Index ausgabe: " << nameCol << endl;
cout << "Inhalt: " << query.value(nameCol).toString().toStdString() << endl;
query.finish();
db.close();
}
Wenn ich die Abfrage mit einem * schreibe um alle Spalten abzufragen, liefert mir query.exec() den Wert fase zurück, von daher gehe ich mal davon aus dass das nicht funktioniert hat. Acuh wenn ich zb. einen Spaltennamen eingebe, den es nicht gibt liefert exec() den Wert false. Da er bei "uersname" den Wert true ausgibt, scheint er in der Taballe die Spalte ja gefunden zu haben.
Bei "Number of Columns" bekomme ich dann den Wert 1, dass heißt ja schonmal, dass die Spalte dich ich gewählt hab anscheinend gefunden wurde.
Ich bekomme es jetzt jedoch nicht hin mir die Werte ausgeben zu lassen.
Code: Alles auswählen
rec.indexOf("username");
Code: Alles auswählen
cout << "Inhalt: " << query.value(nameCol).toString().toStdString() << endl;
Bei dem Befehl query.next() stürzt das Programm weiterhin ab."QSQLQuery::value: not positioned on a valid record".
Ich habe leider keine Idee mehr woran es noch liegen kann. Hoffe von euch weiß noch jemand Rat..
Danke schonmal
okay also query.next() mus drin sein um quasi zumindest das erste element zu bekommen.
Ich habden Code nochmals abgeändert (übersichtlicher und mit Fehlerabfragen):
Der Debugger schmeist bei query.next() folgende Fehlermeldung:

Kann es dara liegen, dass ich mit einer MySQL4 - Datenbank arbeite aber der Treiber MYSQL3 ist ??
Ich habden Code nochmals abgeändert (übersichtlicher und mit Fehlerabfragen):
Code: Alles auswählen
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL3");
db.setHostName("127.0.0.1");
db.setDatabaseName("dbname");
db.setUserName("dbusername");
db.setPassword("dbpassword");
db.setPort(dbport);
if( db.open() )
{
QSqlQuery query;
if( query.prepare("SELECT name FROM jos_users") )
{
if( query.exec() )
{
while (query.next())
{
cout << "Ausgabe: " << query.value(0).toString
().toStdString() << endl;
}
query.finish();
}
}
db.close();
}
Zusammenfassend: Es funktioniert, dass die Datenbank connected wird, die Abfrage vorbereitet und die Abfage ausgeführt wird. Dann is jedoch ende ..Unbehandelte Ausnahme bei 0x04988757 (libmysql.dll) in MyProgram.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x000000fe.
Kann es dara liegen, dass ich mit einer MySQL4 - Datenbank arbeite aber der Treiber MYSQL3 ist ??
Hallo Leute,
ich komme der Lösun näher
Ich hab jetzt herausgefunden, dass mein Programm in Verbindung mit einer Datenbank ( Version: 3.23.58 ) hervorragend funktioniert. Allerdings bekomm ich immer einen Absturz beim "query.next()" Befehel sobald ich mit einer Datenbank ( Version: 4.1.22 ) arbeite.
Außerdem Funktioniert sowas wie query.exec("select *from jos_users")
nicht. Also ich kann keine Abfragen mit * verschicken. Bei der Arbeit mit einer 3-er Datenbank geht das.
Mein Code der mit der 3-er funktioniert aber nich mit der 4-er sieht folgendermaßen aus:
Wäre super wenn mir da jemand weiter helfen könnte, da ich eigentlich mit MySql 4 arbeiten wollte.
Danke
ich komme der Lösun näher
Der Fehler bezieht sich auf folgenden QT-Code aus der Datei "qsql_mysql.cpp":Unbehandelte Ausnahme bei 0x04998757 (libmysql.dll) in MyProgramm.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x000000fe.
Wegen der if-Bedingung kam ich auch auf die Idee mal eine Datenbank mit Version < 40108 zu benutzen, mit der es dann nicht zu diesem Problem kommt.#if MYSQL_VERSION_ID >= 40108
mysql_stmt_data_seek(d->stmt, i);
Außerdem Funktioniert sowas wie query.exec("select *from jos_users")
nicht. Also ich kann keine Abfragen mit * verschicken. Bei der Arbeit mit einer 3-er Datenbank geht das.
Mein Code der mit der 3-er funktioniert aber nich mit der 4-er sieht folgendermaßen aus:
Code: Alles auswählen
void test::db
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setDatabaseName("dbname");
db.setUserName("dbusername");
db.setPassword("dbpassword");
db.setPort(dbport);
if( db.open() )
{
QSqlQuery query;
}
if( query.exec("select name from jos_users") )
{
while (query.next())
{
cout << query.value(0).toInt() << endl;
}
query.finish();
}
db.close();
}
Wäre super wenn mir da jemand weiter helfen könnte, da ich eigentlich mit MySql 4 arbeiten wollte.
Danke
Ich machs immer nach dem Schema:Tuxing hat geschrieben:Hallo Leute,
Danke
Code: Alles auswählen
int Klasse::initDb()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setDatabaseName("dbname");
db.setUserName("dbusername");
db.setPassword("dbpassword");
db.setPort(dbport);
if (!db.open())
{
QMessageBox::critical(this, "Error", "...");
return fail;
}
return success;
}
int Klasse::doSomething()
{
QSqlQuery q("select name from jos_users");
while (q.next())
qDebug() << query.value(0);
return success;
}
okay für alle die vll ein ähnliches problem hatten, hier ist mein Lösung:
Der Fehler waren die MySql treiber. Ich hatte MySQL 4.x installiert und daraus das QT Plugin installiert. Anscheinend hatte der Treiber für MySQL 4 Datenbanken einen Fehler.
Das Problem war gelöst, nachdem ich MySQL 5 installiert hatte und das Plugin neu erstellt. Dann QT neu kompilieren und alles hat funktioniert.
Danke für die vielen Lösungsvorschläge
Der Fehler waren die MySql treiber. Ich hatte MySQL 4.x installiert und daraus das QT Plugin installiert. Anscheinend hatte der Treiber für MySQL 4 Datenbanken einen Fehler.
Das Problem war gelöst, nachdem ich MySQL 5 installiert hatte und das Plugin neu erstellt. Dann QT neu kompilieren und alles hat funktioniert.
Danke für die vielen Lösungsvorschläge