Seite 1 von 1

QSqlQuery::value( hier ein Stringbezeichner ) verwenden

Verfasst: 2. Februar 2009 20:16
von Al_
Hallo
QSqlQuery::value(int) is rasch, aber der int Parameter ist umständlich und fehleranfällig (da der Index ändert, wenn die SQL Query geändert wird).

Folgendes funktioniert (exportPersonen ist eine QSqlQuery Instanz):
#define EXPORTPERSONEN PersonalNr, Vorname, Nachname
enum{ EXPORTPERSONEN };
exportPersonen.prepare("SELECT PersonalNr, Vorname, Nachname FROM Personen WHERE PersonalNr <> 0");
...
int dieNummer = exportPersonen.value(PersonalNr).toInt();
--> PersonalNr kann anstelle von 0 verwendet werden.

Eigentlich möchte ich auch das prepare Statement so schreiben:
exportPersonen.prepare("SELECT EXPORTPERSONEN FROM Personen WHERE PersonalNr <> 0");

Geht aber nicht (da Makros in strings nicht expandiert werden).

Hat jemand eine Lösung?

Gruss, Al_

Verfasst: 2. Februar 2009 20:19
von upsala
Die Doku zu QSqlQuery hat doch so schöne Beispiele für sowas, schon mal angesehen?

Verfasst: 3. Februar 2009 18:46
von Al_
In den Docs sehe ich "int fieldNo = query.record().indexOf("country");"

Ich hoffe auf eine compile-time Lösung.

Verfasst: 3. Februar 2009 20:09
von upsala
Gibts mit Qt-Mitteln nicht.

Verfasst: 22. Februar 2009 08:16
von Al_
Hallo

Ich habe eine zwar unelegante, aber praktikable Lösung gefunden:

Code: Alles auswählen

// header file
#define CREATE_FIELDLIST2(listName, field1, field2) \
   enum{listName ## _ ## field1, listName ## _ ## field2}; \
   const char listName[] = #field1 ", " #field2;

// example how to use this macro
CREATE_FIELDLIST2(employeeData, lastname, firstname);

qDebug() << "SELECT " << employeeData << " FROM employeetable";
qDebug() << "FieldId of lastname = " << employeeData_lastname;
qDebug() << "FieldId of firstname = " << employeeData_firstname;
Die Ausgabe dieses Programmfragments ist dann
  • SELECT lastname, firstname FROM employeetable
    FieldId of lastname = 0
    FieldId of firstname = 1
Meine Vorgabe, dass die Feldnummern compile-time Konstanten sind, ist damit erfüllt. Unelegant ist die Lösung aus zwei Gründen: Erstens sind Makros nicht wirklich typsicher (bestenfalls bekommt man unverständliche Fehlermeldungen). Da meines Wissens nur der Präprozessor Identifier in Strings umwandeln kann, lassen sich Makros aber nicht vermeiden. Zweitens muss die Anzahl Parameter eines Makros fix sein, deshalb muss man bei dieser Lösung für jede Parameteranzahl ein separates Makro schreiben (CREATE_FIELDLIST3, ..4, ..5, ...). Da ich viel SQL Abfragen schreibe, lohnt sich dies für mich trotzdem. Und vielleicht kommt mir doch noch eine elegantere Idee.

Gruss, Al_

Verfasst: 5. März 2009 13:34
von mucmonkey
In all meinen Projekten funktioniert das indexOf() wunderbar.

Code: Alles auswählen

QSqlQuery _query;
//Query füllen und ausführen

QSqlRecord _record = _query.record();
int _posSpalte_DieIchSuche = _record.indexOf("spaltenname");

Verfasst: 7. März 2009 17:09
von Al_
Einverstanden: indexOf(QString) funktioniert. Ist allerdings keine compile-time Konstante. Wahrscheinlich bin ich zu pingelig, aber wenn eine Konstante zur compile-time bekannt ist, so möchte icg sie auch compile-time festlegen können. Meine Lösung erfüllt diese Bedingung, allerdings um den Preis eines uneleganten Präprozessor-Makro.

Gruss, Al_