SQL 2 Varianten Welche ist sinnvoller?
Klar kriegst du einen leeren String, weil nämlich next() nur bei einem SELECT (QSqlQuery::isSelect()) und isActive() true returned und deshalb nie in die Schleife einsteigt.
Wie sieht denn dein DB-Layout aus? Hat deine "int ID"-Spalte auch ein "primary key autoincrement"?
Bei dem Weg über "SELECT last_insert_rowid();" musst du natürlich auf next() ResultSet stellen, um an den Wert zu kommen, aber das wird wohl lastInsertId() auch so machen.
Wie sieht denn dein DB-Layout aus? Hat deine "int ID"-Spalte auch ein "primary key autoincrement"?
Bei dem Weg über "SELECT last_insert_rowid();" musst du natürlich auf next() ResultSet stellen, um an den Wert zu kommen, aber das wird wohl lastInsertId() auch so machen.
oh das ist so kompliziert.
nein ich hab keine spalte mit primery key gemacht, weil nach der sqlite doku jeder Table automatisch eine ROWID hat auto increment nutzt.
Ja aber in dem Beispiel in der qt doku qsqlquery machen die das mit dem next() auch so.
und außerdem hab ich doch select geschrieben, aber das wird ja gleich ausgeführt und dann ist er ja fertig.
nein ich hab keine spalte mit primery key gemacht, weil nach der sqlite doku jeder Table automatisch eine ROWID hat auto increment nutzt.
Ja aber in dem Beispiel in der qt doku qsqlquery machen die das mit dem next() auch so.
und außerdem hab ich doch select geschrieben, aber das wird ja gleich ausgeführt und dann ist er ja fertig.
Ich hab grad noch etwas gespielt. Das mit der automatischen RowID wusste ich noch nicht
Ich nehme fast an, es liegt an deinem "Drumherum". Wenn ich etwas nicht raffe schreib ich mir immer kleine Testprogramme, die nur auf das Problem fokussiert sind. So schaut das dann in etwa aus:
Geh es durch, lass es laufen, spiel damit
"PRIMARY KEY AUTOINCREMENT" braucht es nur, wenn du willst dass sqlite für die ROWID jene spezielle Spalte verwenden soll (oben: Table test2, COL id). Wenn du keine eigene Spalte für jene ID hast, kannst du trotzdem danach SELECTieren: "WHERE ROWID='20'" (oder so), auch wenn ROWID keine eigene, von dir angelegte Spalte ist.
Ich nehme fast an, es liegt an deinem "Drumherum". Wenn ich etwas nicht raffe schreib ich mir immer kleine Testprogramme, die nur auf das Problem fokussiert sind. So schaut das dann in etwa aus:
Code: Alles auswählen
#include <QSqlDatabase>
#include <QString>
#include <QVariant>
#include <QSqlQuery>
#include <QDebug>
int main() {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":memory:");
db.open();
qDebug() << "No autoincrement";
QSqlQuery q = db.exec("CREATE TABLE test1 (id INTEGER, name VARCHAR)");
qDebug() << q.isActive();
q = db.exec("INSERT INTO test1 (name) VALUES ('Semmelknödel')");
qDebug() << "Last Id:" << q.lastInsertId().toInt();
q = db.exec("INSERT INTO test1 (name, id) VALUES ('Ödi', 20)");
qDebug() << "Last Id:" << q.lastInsertId().toInt();
qDebug() << "With autoincrement";
q = db.exec("CREATE TABLE test2 (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR)");
qDebug() << q.isActive();
q = db.exec("INSERT INTO test2 (name) VALUES ('Semmelknödel')");
qDebug() << "Last Id:" << q.lastInsertId().toInt();
q = db.exec("INSERT INTO test2 (name, id) VALUES ('Ödi', 20)");
qDebug() << "Last Id:" << q.lastInsertId().toInt();
qDebug() << "Using the SQLite ROWID";
q = db.exec("SELECT name, id FROM test1 WHERE ROWID='1'");
qDebug() << q.isActive();
// Das while ist eigentlich unnötig, da ROWID eindeutig ist. Ich mach es zum Testen hier trotzdem mal.
while(q.next()) qDebug() << q.value(0).toString() << q.value(1).toInt();
q = db.exec("SELECT name, id FROM test2 WHERE ROWID='20'");
qDebug() << q.isActive();
while(q.next()) qDebug() << q.value(0).toString() << q.value(1).toInt();
q = db.exec("SELECT last_insert_rowid();");
qDebug() << q.next();
qDebug() << "Last Insert ID:" << q.value(0).toInt();
}
"PRIMARY KEY AUTOINCREMENT" braucht es nur, wenn du willst dass sqlite für die ROWID jene spezielle Spalte verwenden soll (oben: Table test2, COL id). Wenn du keine eigene Spalte für jene ID hast, kannst du trotzdem danach SELECTieren: "WHERE ROWID='20'" (oder so), auch wenn ROWID keine eigene, von dir angelegte Spalte ist.
Mal davon abgesehen, daß diese Query überhaupt nichts tun dürfte außer einen Fehler zu melden:
Aber dazu müßte man sich ja mal die Datenbank-Logs oder den zurückgemeldeten Fehler ansehen.
Code: Alles auswählen
QSqlQuery query("INSERT into person (name)"
"VALUES ("+line->text()+")");
ok danke das sieht supper aus und klappt auch gut.
Aber du erstellest deine querys anderes als ich.
Ich hab die Querys in einer anderen Klasse und kann nicht auf db.exec zugreifen.
QSqlQuery q2("INSERT INTO group (groupname) VALUES ('Hallo')");
qDebug() << q2.isActive();
qDebug() << q2.lastInsertId().toInt();
Das hier liefert immer false und 0.
Aber du erstellest deine querys anderes als ich.
Ich hab die Querys in einer anderen Klasse und kann nicht auf db.exec zugreifen.
QSqlQuery q2("INSERT INTO group (groupname) VALUES ('Hallo')");
qDebug() << q2.isActive();
qDebug() << q2.lastInsertId().toInt();
Das hier liefert immer false und 0.
Schau dir die Doku zu QSqlQuery an. Speziell die Konstruktoren. Interessieren tut dich der zweite, das ist der den du verwendest. 1. Param = der Query, zweiter Param = die db. Schau dir durch was da passiert, du brauchst das db-Objekt gar nicht.Nvidia hat geschrieben:Ich hab die Querys in einer anderen Klasse und kann nicht auf db.exec zugreifen.
Trotzdem ist deine Aussage nicht korrekt
QSqlDatabase verwaltet für dich alle Verbindungen. Schau dir die Doku zu QSqlDatabase::addDatabase an. 1. Param = der Treibername, 2. Param = connectionName. Du kannst mit passendem connectionName von überall aus das db-Objekt holen über QSqlDatabase::database(). Gib keinen an, und du bekommst die defaultConnection (das ist eh das was du bisher machst).
Code: Alles auswählen
QSqlDatabase db = QSqlDatabase::database("test");
db.open();
QSqlQuery q2 = db.exec("CREATE TABLE test1 (id INTEGER, name VARCHAR)");
qDebug() << q2.isActive();
q2 = db.exec("INSERT INTO group (groupname) VALUES ('Hallo')");
qDebug() << q2.isActive();
qDebug() << q2.lastInsertId().toInt();
QSqlQuery::exec: database not open
Das wissen nur die Götter...Nvidia hat geschrieben:ok das klingt gut. Warum ist die Datenbank schon wieder zu?
QSqlQuery::exec: database not open
Wie erstellst du deine DB? Zeig mal die dazugehörige Zeile mit dem "addDatabase()", und wie du die einrichtest. Nennst du die Verbindung denn auch "test" beim Erstellen?
Code: Alles auswählen
static bool database()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE","test");
db.setDatabaseName("hallo");
if (!db.open())
{
...
}
....
}
Und führst du database() auch aus? Wenn ich mir nämlich ein nicht existentes db-Objekt aus den verwalteten hole, krieg ich das selbe Verhalten:
Ist zwar aus der Python-Console, aber das macht ja nix
Gibt db.open() auf deine "test"-db auch false?
BTW sollte ein neuerliches open() nicht nötig sein, wenn die db eh schon geöffnet wurde.
Code: Alles auswählen
>>> db = QSqlDatabase.database("ich_existiere_nicht")
>>> db.open()
False
>>> db.exec_("SELECT last_insert_rowid();")
QSqlQuery::exec: database not open
<PyQt4.QtSql.QSqlQuery object at 0x7f919855eef0>
Gibt db.open() auf deine "test"-db auch false?
BTW sollte ein neuerliches open() nicht nötig sein, wenn die db eh schon geöffnet wurde.