QSqlQuery::value( hier ein Stringbezeichner ) verwenden

Alles rund um die Programmierung mit Qt
Antworten
Al_
Beiträge: 17
Registriert: 10. Januar 2009 15:27
Wohnort: Schweiz

QSqlQuery::value( hier ein Stringbezeichner ) verwenden

Beitrag 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_
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Die Doku zu QSqlQuery hat doch so schöne Beispiele für sowas, schon mal angesehen?
Al_
Beiträge: 17
Registriert: 10. Januar 2009 15:27
Wohnort: Schweiz

Beitrag von Al_ »

In den Docs sehe ich "int fieldNo = query.record().indexOf("country");"

Ich hoffe auf eine compile-time Lösung.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Gibts mit Qt-Mitteln nicht.
Al_
Beiträge: 17
Registriert: 10. Januar 2009 15:27
Wohnort: Schweiz

Beitrag 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_
mucmonkey
Beiträge: 5
Registriert: 5. März 2009 10:31
Wohnort: München

Beitrag 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");
Al_
Beiträge: 17
Registriert: 10. Januar 2009 15:27
Wohnort: Schweiz

Beitrag 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_
Antworten