2016-05-08 7 views
1

QSqlQuery Class documentation eine Dose Nach implementiert einen Einfügevorgang in einer MySQL-Datenbank, das heißt wie folgt aus:QSqlQuery vollständige Struktur anstelle einzelner Felder einfügen?

QSqlQuery query; 
query.prepare("INSERT INTO person (id, forename, surname) " 
       "VALUES (:id, :forename, :surname)"); 
query.bindValue(":id", 1001); 
query.bindValue(":forename", "Bart"); 
query.bindValue(":surname", "Simpson"); 
query.exec(); 

Es funktioniert. Aber es ist fragil, nicht wahr? Es wird nicht mehr funktionieren (weil Namen hart codiert sind), wenn ein Spaltenname nicht übereinstimmt, wenn der Datenbankprogrammierer einen Spaltennamen im MySQL-Skript ändert, d. H. surname zu lastname.

Was mir in den Sinn kam, war, den ganzen Mechanismus so zu ändern, dass anstatt einzelne Felder einzufügen, ein großes Objekt (vielleicht eine Struktur aus den einzelnen Feldern) eingefügt werden sollte. Und dann sollten auf der db-Seite die Felder wieder in eine Reihe von Feldern aufgeteilt werden, d. H. Unter Verwendung einer Ansicht oder eines Triggers.

Gehe ich in die richtige Richtung?

Ich freue mich über allgemeine Kommentare zu diesem Thema.

+0

so, suchen Sie nach einer Möglichkeit der Implementierung, wo Sie die Spalte von 'surname' zu' lastname' in der db ändern kann, und dann die C++ - Code wird automatisch wissen, dass Werte, die in "Nachname" gehen sollten, nun in "Nachname" gehen, ohne dass die C++ - Seite geändert wird. – Mike

+0

Nicht genau, aber da du mit dieser verwandten Frage gekommen bist, hast du vielleicht eine Antwort auf deine eigene Frage (die meiner sehr nahe ist - Frage bearbeitet, um meinen Ansatz klarer zu machen) und in diesem Fall interessiert mich dein Ansatz. Können Sie die Abfrage auslagern und zur Laufzeit laden? – KcFnMi

+0

Entschuldigung, tatsächlich habe ich meine Frage gestellt, weil ich denke, dass es keine Möglichkeit gibt, das zu implementieren. Vielleicht kann mich hier jemand korrigieren. . . – Mike

Antwort

0

Nun, es gibt einen Weg, aber Sie müssen sicher sein, dass sich die Struktur der Tabellen- und Spaltenbedeutung nicht ändert und Ihre Abfrage Daten jeder einzufügenden Spalte enthält.

Erstens müssen Sie alle Informationen über Ihre Tabelle auswählen:

SELECT c.column_name FROM information_schema.columns c 
WHERE c.table_name = 'some_table_name' 
ORDER BY c.ordinal_position ASC 

Zweitens können Sie den Code ändern so sein. Ich universelle Methode, die Sie bereits Daten bekannt Bedeutung haben:

QList<QVariant> valuesList { QVariant(1), QVariant("Bart"), QVariant("Simpson") }; 
QList<QPair<QString, QVariant>> varList; 
QSqlQuery query; 
query.exec("SELECT @rownum := @rownum + 1 AS row_num, c.column_name 
      FROM information_schema.columns c, (SELECT @rownum := -1) r 
      WHERE c.table_name = 'some_table_name' 
      ORDER BY c.ordinal_position ASC"); 
while(query.next()) 
    colList << QPair<QString, QString>(query.value(1).toString(), 
       valuesList.at(query.value(0).toInt())); 

QString queryString = "INSERT INTO person (%1) " 
         "VALUES (%2)"; 

QString insertColsString; 
QString bindColsString; 

for(int i = 0; i < colList.size(); i++) { 
    insertColsString += colList.at(i).first + ", "; 
    bindColsString += ":" colList.at(i).first + ", "; 
} 

if(!insertColsString.isEmpty()) { 
    insertColsString.chop(2); 
    bindColsString.chop(2); 
} 

query.prepare(queryString.arg(insertColsString, bindColsString)); 

for(int i = 0; i < colList.size(); i++) 
    query.bindValue(":" + colList.at(i).first, colList.at(i).second); 

query.exec(); 
Verwandte Themen