2016-09-09 1 views
0

Ich habe erfolgreich mit meiner Datenbank verbunden, aber wenn ich 2 Zellen aus meiner SQL db auswählen, um den Wert für meine beiden Variablen festzulegen, tut es nichts. Ich habe kein Problem, Daten in die Datenbank einzufügen. Ich habe verschiedene Ansätze versucht, ohne Erfolg. Könnte es sein, dass ich versuche, ein String-Format für Doppel zu verwenden?Wie erhalten Sie Gleitkomma-Ergebnisse von einer SQL-Abfrage?

double userHeight; 
double userWeight; 
QSqlQuery query; 
QString retreiveUserHeight = 
    QString("SELECT Height, Weight FROM SQL1 WHERE Username='joejoe'"); 
query.prepare(retreiveUserHeight); 
query.bindValue(0,"Height"); 
query.bindValue(1, "Weight"); 
query.exec(); 
userHeight = query.value(0).toInt(); 
userWeight = query.value(1).toInt(); 

Ich bin ziemlich sicher, es gibt einen kleinen Fehler in der Syntax, die dieses Unglück verursacht, aber ich habe es nicht gelungen, es zu finden. Danke für Ihre Hilfe.

qDebug() << "calculated" << 703*(userWeight/(userHeight*userHeight)) 
     << userWeight << userHeight ; 

Heres die Debug-Ausgabe:

calculated nan 0 0 

Antwort

1
// Obtain username from somewhere 
QString username = "joejoe"; 


// Check whether DB is open 
if(db->isOpen()) 
{ 
    QSqlQuery query; 

    double userHeight; 
    double userWeight; 


    // Prepare select statement 
    query.prepare ("SELECT Height , Weight FROM SQL1 WHERE Username = :username"); 
    query.bindValue (":username" , username); 
    query.exec  (); 

    // Check if something went wrong when executing your query 
    if(query.lastError().text().trimmed() == "") 
    { 
     // Loop through all results and handle them accordingly 
     while(query.next()) 
     { 
      userHeight = query.value(0).toDouble(); 
      userWeight = query.value(1).toDouble(); 

      qDebug() << "calculated" << 703 * (userWeight/(userHeight * userHeight)) << userWeight << userHeight; 
      qDebug() << "---------------------------------"; 
     } 
    } 
    else 
    { 
     // Display the error that occured 
     QMessageBox::critical(this , tr("SQL Error") , query.lastError().text()); 
    } 
} 

Ich gehe davon aus, dass es so ist, wie Sie es aussehen wollten.

Ich habe eine Fehlerüberprüfung eingefügt und Ihre Abfrage so korrigiert, dass sie .bindValue() korrekt verwendet, da sie nicht für die Rückgabewerte, sondern für die Eingabe verwendet werden soll, wie in der WHERE zu sehen ist.

Da ich nichts über Ihre SQL-Tabelle weiß, habe ich eine Schleife enthalten, um alle Ergebnisse Ihrer Abfrage zu durchlaufen. Das kann natürlich geändert werden.

Abgesehen davon, dass, wenn Sie double s verwenden Sie das Ergebnis werfen sollte .toDouble() statt .toInt()

+0

Ihre Lösung funktioniert perfekt und ist Benutzername spezifisch. – Gepard

1

eine Reihe schwerwiegender Probleme mit diesem Code Es gibt keine. Beginnen wir mit dem Konzept der vorbereiteten SQL-Abfragen. Wikipedia listet two reasons für mit Prepared Statements:

  • Der Aufwand für die Erstellung und Optimierung der Aussage nur einmal entstanden ist, obwohl die Anweisung mehrmals ausgeführt wird. [...]
  • Vorbereitete Anweisungen sind gegen SQL-Injection resistent, weil Parameterwerte, die später mit einem anderen Protokoll übertragen werden, nicht korrekt maskiert werden müssen.

Keiner dieser Gründe gilt in Ihrem Code; Sie führen die Abfrage nur einmal aus, und Sie spleißen keine Eingaben in die Zeichenfolge. In der Tat ist der einzige Eingang in Ihrer Anfrage an alle Benutzernamen, die "joejoe" hartcodiert ist:

"SELECT Height, Weight FROM SQL1 WHERE Username='joejoe'" 

Da es keine Variable Eingänge, eine vorbereitete Abfrage mit nicht viel Sinn machen. Man zündet auch nicht die folgenden Zeilen:

query.bindValue(0,"Height"); 
query.bindValue(1, "Weight"); 

Größe und Gewicht sind Ausgänge aus dieser Abfrage, nicht Eingänge. Im Abschnitt Qt docs for QSqlQuery mit dem Titel "Ansätze zu Bindungswerten" finden Sie eine Erklärung, wie dies funktionieren soll. Die API von Qt zum Binden vorbereiteter SQL-Abfragen ist ziemlich typisch für Datenbankbibliotheken, hier gibt es nichts, was die Welt erschüttert.

Dann erhalten wir dazu:

userHeight = query.value(0).toInt(); 
userWeight = query.value(1).toInt(); 

Sowohl die Variablen, die Sie in hier gerade lesen wurden als verdoppelt erklärt, aber Sie anrufen toInt() auf dem zurück QVariant statt toDouble(). Ich weiß nicht, welche (wenn überhaupt!) Werte in Ihrer Datenbank sind, aber es ist möglich, dass sie während der Konvertierung von double nach int auf Null abgerundet werden, wenn die Werte zwischen -1,0 und 1,0 liegen.

Das heißt, Sie tun keine Fehlerprüfung überhaupt. Die Methoden prepare() und exec() geben Boolets zurück, die angeben, ob sie erfolgreich waren oder fehlgeschlagen sind. Gleichermaßen sagen Ihnen sowohl toInt() als auch toDouble(), ob sie erfolgreich waren oder fehlgeschlagen sind, wenn Sie einen Zeiger auf einen bool übergeben. Es ist erwähnenswert, dass beide Methoden bei einem Fehler auch einen Nullwert zurückgeben.

Verwandte Themen