Seite 1 von 1

(Erledigt) [SQLITE] Problem mit SqlQuery (ConnectionError?)

Verfasst: 11. April 2011 09:51
von Lichter
Guten Morgen,
ich habe leider ein Problem beim Einfügen verschiedener Daten aus einem Dialog in eine SQLite Datenbank.

Meine Schritte sind folgende:
1. Aufbauen der Verbindung (extra Funktion)
2. QSqlQuery auf folgende Weise: [QSqlQuery query(db);]
db ist in der Klasse deklariert : QSqlDatabase db;

3. query.prepare() klappt - d.h. wird true zurückgegeben (daran kanns nicht liegen)

4. query.exec() liefert false, query.lasterror() sagt "Connection Error"

Ich habe überprüft ob die Datenbank noch "offen" ist - mit db.IsOpen() - es wird false zurückgegeben. Wie kann ich sicherstellen, dass die Datenbank erst dann geschlossen wird, wenn ich es "angebe"? Im Code steht nirgendwo etwas von db.close()?! Gibt es eine Möglichkeit die Datenbank Verbindung "global" zu machen?

Entschuldigt bitte, falls ich wirres Zeug rede, bin auf diesem Gebiet noch Anfänger.

PS: Falls es hilft(?): die Tabellen existieren und wurden extern erstellt.

Verfasst: 11. April 2011 10:28
von franzf
Wir brauchen ein komplettes Code-Beispiel, um etwas sagen zu können. Also den ganzen Schwupps von db-Initialisierung bis query.exec().
Und die dbs werden schon global gespeichert, siehe

Code: Alles auswählen

QSqlDatabase QSqlDatabase::database ( const QString & connectionName = QLatin1String( defaultConnection ), bool open = true ) [static]

Verfasst: 11. April 2011 10:44
von Lichter
Verbindungsaufbau:

Code: Alles auswählen

void Dialog_add::SetupConnection()
{
	QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");	// QSQLITE ist der Datenbanktreiber in Stringform
	db.setDatabaseName("myDb.db");	// SQLite Datei öffnen
	if(!db.open())
	{
		// Fehler, keine Verbindung
		QMessageBox::warning(this, "Fehler beim Aufbau der Verbindung", "Es konnte keine Verbindung aufgebaut werden!", QMessageBox::Ok);
	}	
}

Code: Alles auswählen

void Dialog_add::DialogAccepted()
{
// Daten in die Datenbank schreiben
		QSqlQuery query(db);					
		query.prepare("INSERT INTO Test( Computer1, Computer2, , Wer, Was, Wann, Datumende, Problem,  Eingangsdatum, Titel, Zeilennummer) "
			"VALUES(:Computer1,:Computer2,:Wer,:Was,:Wann,:Datumende, :Problem, :Eingangsdatum, :Titel, :Zeilennummer)");
	
		// --- Data binding binding
		
		query.bindValue(":Computer1", Computer1);
		query.bindValue(":Computer2", Computer2);
		query.bindValue(":Wer", Wer);
		query.bindValue(":Was", Was);
		query.bindValue(":Wann", Wann);
		query.bindValue(":Datumende", Datumende);
		query.bindValue(":Problem", Problem);
		query.bindValue(":Eingangsdatum", Eingangsdatum);
		query.bindValue(":Titel", Titel);
		query.bindValue(":Zeilennummer", Zeilennummer);
		
		query.exec();
		QSqlError err = query.lastError();
		qDebug() << err.text(); 
}

Verfasst: 11. April 2011 11:16
von franzf
Du erstellst in SetupConnection() eine connection mit default-connectionName. Dein db-Object ist in SetupConnection lokal! Wenn du db auch in der KLasse deklariert hast, ist das damit NICHT initialisiert, und funktioniert somit auch nicht.
In DialogAccepted() übergibst du dem Query ein Objekt "db". Das ist mitnichten das aus SetupConnection! Dass den Parameter einfach weg, dann nimmt der Query die default-Connection, und alles sollte funktionieren.

Verfasst: 11. April 2011 11:25
von Lichter
Ich hab aus QSqlQuery query(db); => QSqlQuery query; gemacht, dennoch gibt query.exec() false zurück. Der Grund: Connection Error

Kann es theoretisch auch damit zusammenhängen, dass die Datenbank mit einem externen Programm erstellt wurde? Oder ist das irrelevant?

Edit: Ich habe testhalber mal eine andere query erstellt, die eine neue Tabelle in der selben Datenbank ausführt, diese kann erfolgreich ausgeführt werden.
Mir ist aufgefallen, dass ich in meiner Query keine ID (die zur Tabelle gehört, aber auto increment ist) angebe. Folgt der Fehler vielleicht daraus? Aber warum gibt dann prepare() true zurück?
Und wenn ja, wie implementiere ich dieses ID-Feld (einen Wert zuweisen, würde doch nichts bringen, da auto-increment)?

Editr2: Die Implementation für ein auto-increment Feld wird einfach mit NULL angegeben (siehe: http://wiki.forum.nokia.com/index.php/C ... base_in_Qt). Ich habe also die Query angepasst, prepare() gibt true zurück, exec() ist dennoch nicht möglich!

Verfasst: 11. April 2011 13:52
von franzf
Warum prepare true zurückgibt und exec false, steht in der Doku.
Wie hast du die DB erstellt?
Den Link über SQLite + Primary Key + Autoincrement kennst du?
http://www.sqlite.org/faq.html#q1

Ohm ich seh auch grad noch nen Fehler in deinem Query-String:
INSERT INTO Test( Computer1, Computer2, , Wer, Was, Wann, Datumende, Problem, Eingangsdatum, Titel, Zeilennummer)

Verfasst: 12. April 2011 11:38
von Lichter
Ich denke, ich habe den Fehler gefunden.
Nachdem ich die Tabelle erneut erstellt habe (mit den "richtigen" Datatypes von SQlite) funktioniert nun alles.