QSQLITE, false als Rückgabe

Alles rund um die Programmierung mit Qt
Antworten
Squall
Beiträge: 6
Registriert: 14. Mai 2009 20:22

QSQLITE, false als Rückgabe

Beitrag von Squall »

Nabend,

in einem Programm von mir verwende ich SQLite als Datenbank und dort habe ich eine Spalte einer Tabelle in der BOOLEAN-Werte drinstehen... Wenn dort nun "true" drinsteht, wird es bei einem Query zurückgegeben. Bei einem "false" wird jedoch gar nichts zurückgegeben...

Ich habe es per Konsole mal probiert:

Code: Alles auswählen

$ sqlite3 db/spa "SELECT aenderbar FROM gruppen"
und ich bekam alle Werte, auch die mit false...

Kann es sein, dass da etwas mit dem QSQLITE-Treiber nicht stimmt? Wie soll ich nun herausfinden, ob es nun false ist?
Klar! ich könnte einfach hergehen und sagen, sofern nichts wiedergegeben wird, ist es false, jedoch ist es ein wenig problematischer, da ich die Datenbank dynamisch auslese..

Hat wer Vorschläge?

Danke
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: QSQLITE, false als Rückgabe

Beitrag von franzf »

Squall hat geschrieben:in einem Programm von mir verwende ich SQLite als Datenbank und dort habe ich eine Spalte einer Tabelle in der BOOLEAN-Werte drinstehen...
Kannst du mal bitte dein Tabellen-Layout (in SQL-Syntax) angeben?
Dann schau dir mal die Links an:
*) http://sqlite.org/datatype3.html
*) http://groups.google.com/group/android- ... 7fe2231cb2
Squall
Beiträge: 6
Registriert: 14. Mai 2009 20:22

Beitrag von Squall »

Die Tabelle als SQL-Anweisung:

Code: Alles auswählen

CREATE TABLE gruppen (
	id INTEGER PRIMARY KEY AUTOINCREMENT DEFAULT NULL,
	bez VARCHAR(20) NOT NULL UNIQUE,
	beschr VARCHAR(100),
	aenderbar BOOLEAN DEFAULT 'true'
);
Also SQLite ist in mancher Hinsicht wirklich seltsam... Naja.

Also die Seite hatte ich auch gesehen, doch in der SQLite-Version 2 gibt es BOOLEAN wie es scheint: http://www.sqlite.org/datatypes.html

Mir ist das Ganze irgendwie zu dämlich.. Ich wandle die Bool-Werte einfach in Zahlenwerte um und gut is. :D Danke für deine Hilfe!
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Der Witz an sqlite ist ja scheinbar, dass es Typlos ist. Drum wird ein "BOOLEAN" wohl als String gespeichert werden, du musst dich selber drum kümmern das richtig zu konvertieren.
Mit nem int (0=false, 1=true, z.B.) geht das ja viel leichter :)
Aber irgendwie trotzdem komisch/ungewohnt:

Code: Alles auswählen

sqlite> CREATE TABLE test (id INTEGER);
sqlite> INSERT INTO test (id) VALUES ("Na was ein string");
sqlite> SELECT * FROM test;
Na was ein string
sqlite>
aber

Code: Alles auswählen

sqlite> CREATE TABLE test2 (id INTEGER PRIMARY KEY);
sqlite> INSERT INTO test2 (id) VALUES ("Na was ein string");
SQL error: datatype mismatch
sqlite> INSERT INTO test2 (id) VALUES (2);
sqlite>
Aber vorsicht: INTEGER PRIMARY KEY == AUTO INCREMENT.
Squall
Beiträge: 6
Registriert: 14. Mai 2009 20:22

Beitrag von Squall »

Ich habe es nun in INTEGER geändert ->

Code: Alles auswählen

CREATE TABLE gruppen (
	id INTEGER PRIMARY KEY AUTOINCREMENT DEFAULT NULL,
	bez CHAR NOT NULL UNIQUE,
	beschr CHAR,
--	aenderbar BOOLEAN DEFAULT 'true'
	aenderbar INTEGER DEFAULT 1
);
Doch das bringt nur noch mehr Frustration... :(

Ich habe mir ein kleines Testprogramm geschrieben:
a.pro:

Code: Alles auswählen

TEMPLATE = app
TARGET = 
DEPENDPATH += .
INCLUDEPATH += .

HEADERS += main.h
SOURCES += main.cpp
QT      += sql
main.cpp

Code: Alles auswählen

#include "main.h"

int main(int argv, char *argc[])
{
	QApplication app(argv, argc);
	QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
	db.setDatabaseName("test.db");
	int x;
	
	if(!db.open())
	{
		qDebug() << db.lastError().text();
		return -1;
	}
	
	QSqlQuery query("SELECT * FROM test");
	while(query.next())
	{
		x = 0;
		while(query.value(x).toBool())
		{
			qDebug() << x << query.value(x).toString();
			x++;
		}
	}
	return 0;
}
main.h

Code: Alles auswählen

#include <QDebug>
#include <QApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QVariant>
#include <QString>
#include <QSqlError>
test.sql:

Code: Alles auswählen

CREATE TABLE test(
	id INTEGER PRIMARY KEY AUTOINCREMENT NULL,
	zahl INTEGER
);

INSERT INTO test(zahl) VALUES(0);
INSERT INTO test(zahl) VALUES(0);
INSERT INTO test(zahl) VALUES(1);
INSERT INTO test(zahl) VALUES(0);
INSERT INTO test(zahl) VALUES(1);
INSERT INTO test(zahl) VALUES(1);
INSERT INTO test(zahl) VALUES(0);
INSERT INTO test(zahl) VALUES(0);
INSERT INTO test(zahl) VALUES(1);
INSERT INTO test(zahl) VALUES(0);
INSERT INTO test(zahl) VALUES(1);
Möchtest du raten, welche Daten es nicht ausgegeben hat?
Also ich weiß ja nicht, aber ich glaube nicht, dass das im Sinne der SQLite-Entwickler liegt/lag... Kann es sein, dass der QSQLITE-Treiber einfach unausgereift ist? Ich meine, ihm steht ja nicht einmal sie size()-Methode zur Verfügung. :?

Danke und einen schönen Abend noch!
HappyEnding
Beiträge: 26
Registriert: 5. März 2009 14:15

Beitrag von HappyEnding »

Ich hab mich vor kurzem auch mit SQLite rumgeschlagen und hatte so meine Probleme, evtl hilft dir mein Thread ja weiter.

http://qtforum.de/forum/viewtopic.php?t=9105
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Und möchtest du raten warum es nicht ausgegeben wird?

Code: Alles auswählen

 while(query.next()) 
   { 
      x = 0; 
      while(query.value(x).toBool()) 
      { 
         qDebug() << x << query.value(x).toString(); 
         x++; 
      } 
   }
Weil das so absoluter Käse ist :)
query.value(x).toBool() liefert schon den Variant in einen Bool konvertiert zurück! Klar, wenn da eine 0 in der Spalte steht, gibt es false...
Außerdem... was möchtest du mit der zweiten Schleife bezwecken?

Änder das mal bitte so ab:

Code: Alles auswählen

QSqlQuery query("SELECT * FROM test");
    int colBool = query.record().indexOf("zahl");
    int colId = query.record().indexOf("id");
    qDebug() << colId << colBool;
    while(query.next()) 
    { 
        if(query.value(colBool).canConvert(QVariant::Bool))
        { 
            qDebug() << query.value(colId).toInt() << query.value(colBool).toBool(); 
        } 
    }
Und du wirst über das Ergebnis stolz sein!

Code: Alles auswählen

$ ./9144_SQLite_Bool
0 1
1 false
2 false
3 true
4 false
5 true
6 true
7 false
8 false
9 true
10 false
11 true
Viel Spaß damit
Franz
Squall
Beiträge: 6
Registriert: 14. Mai 2009 20:22

Beitrag von Squall »

Okay, darüber hatte ich noch nicht nachgedacht..
Man kann mithilfe dieser Schleifenkonstruktion alle Zeilen und Spalten auslesen, ohne dass ich weiß, wie viele Spalten ich wirklich habe, nun ja, bis auf die Boolwerte... :roll:

Gibt es denn sonst noch eine Möglichkeit, die Anzahl der Spalten herauszufinden? Ich meine, wie soll man sonst alle Spalten dynamisch auslesen?

Danke
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Squall hat geschrieben:Okay, darüber hatte ich noch nicht nachgedacht..
Man kann mithilfe dieser Schleifenkonstruktion alle Zeilen und Spalten auslesen, ohne dass ich weiß, wie viele Spalten ich wirklich habe, nun ja, bis auf die Boolwerte... :roll:

Gibt es denn sonst noch eine Möglichkeit, die Anzahl der Spalten herauszufinden? Ich meine, wie soll man sonst alle Spalten dynamisch auslesen?

Danke
Aber du hast nur 2 Spalten, und wenn du x hochzählst über die Anzahl der Spalten hinaus hast du keinen Gültigen Wert! Verwechsel bitte nicht Spalten und Zeilen. Die Spalten legen die Namen/Typen fest, und in den Zeilen stehen komplette Datenzätze.
Die Anzahl und Namen der Spalten deiner Tabelle kriegst du mit
QSqlRecord QSqlQuery::record()
Anzahl und Name der Spalten kannst du der Doku zu QSqlRecord entnehmen.
Squall
Beiträge: 6
Registriert: 14. Mai 2009 20:22

Beitrag von Squall »

franzf hat geschrieben:Aber du hast nur 2 Spalten, und wenn du x hochzählst über die Anzahl der Spalten hinaus hast du keinen Gültigen Wert!
Das war ja auch mein Hintergedanke.^^ Wenn ich so lange hochzählen lasse und prüfe, ob ein, nun ja, wahrer Wert dabei herauskommt, sind noch weitere Spalten vorhanden. :)

In meinem Projekt habe ich zwei Tabellen; eine mit 16 und die andere mit 2 Tabellen und fast jede hat eine andere Anzahl an Spalten. Muss ich nun für jede Spalte eine eigene Methode zum Auslesen erstellen, würde es umständlich werden, daher hatte ich versucht es dynamisch zu gestalten. :D
Anfangs war aber auch noch nichts mit Wahrheitswerten geplant, sodass ich mir um solch ein Problem gar keine Sorgen gemacht habe -- tja, dumm gelaufen.^^

Die record-Methode ist mir noch nicht aufgefallen, aber danke für den Verweis. Ich denke damit werde ich etwas anfangen können! :)

Aber wie ist das denn nun? SQLite ist Datentyplos, zumindest in gewissem Maße, hat aber dennoch Datentypen. Laut der Doku der 3er-Version sind es NULL, TEXT, REAL, BLOB und INTEGER. Datentypen wie CHAR sind letztenendes nur Referenzen auf andere Datentypen, wie ich verstanden habe.
Doch was ist nun mit Bool? In SQLite2 war es ja anscheinend vorhanden aber wie sieht es nun mit SQLite3 aus?
Antworten