Ausführen von SQL-Anweisungen
Die Klasse „ QSqlQuery “ bietet eine Schnittstelle zum Ausführen von SQL-Anweisungen und zum Durchlaufen der Ergebnismenge einer Abfrage.
Die im nächsten Abschnitt beschriebenen Klassen „ QSqlQueryModel “ und „ QSqlTableModel “ bieten eine übergeordnete Schnittstelle für den Zugriff auf Datenbanken. Wenn Sie mit SQL nicht vertraut sind, sollten Sie vielleicht direkt zum nächsten Abschnitt („Verwendung der SQL-Modellklassen“) springen.
Ausführen einer Abfrage
Um eine SQL-Anweisung auszuführen, erstellen Sie einfach ein ` QSqlQuery `-Objekt und rufen Sie ` QSqlQuery::exec()` wie folgt auf:
QSqlQuery query;
query.exec("SELECT name, salary FROM employee WHERE salary > 50000");Der Konstruktor von ` QSqlQuery ` akzeptiert ein optionales ` QSqlDatabase `-Objekt, das angibt, welche Datenbankverbindung verwendet werden soll. Im obigen Beispiel geben wir keine Verbindung an, sodass die Standardverbindung verwendet wird.
Tritt ein Fehler auf, gibt ` exec()` ` false` zurück. Der Fehler ist dann über ` QSqlQuery::lastError()` abrufbar.
Navigieren im Ergebnissatz
QSqlQuery ermöglicht den Zugriff auf die Ergebnismenge Datensatz für Datensatz. Nach dem Aufruf von ` exec()` befindet sich der interne Zeiger von ` QSqlQuery` eine Position vor dem ersten Datensatz. Wir müssen QSqlQuery::next() einmal aufrufen, um zum ersten Datensatz zu gelangen, und anschließend wiederholt next() aufrufen, um auf die anderen Datensätze zuzugreifen, bis false zurückgegeben wird. Hier ist eine typische Schleife, die alle Datensätze der Reihe nach durchläuft:
while (query.next()) {
QString name = query.value(0).toString();
int salary = query.value(1).toInt();
qDebug() << name << salary;
}QSqlQuery::value QVariant int QString QByteArray QVariant::toString QVariant::toInt QString intDie Funktion ` QSqlQuery::value()` gibt den Wert eines Feldes im aktuellen Datensatz zurück. XML-Ph-0003@deepl.internal
Einen Überblick über die empfohlenen Typen für die Verwendung mit Qt-unterstützten Datenbanken finden Sie in dieser Tabelle.
Sie können innerhalb des Datensatzes mit den Funktionen ` QSqlQuery::next()`, ` QSqlQuery::previous()`, ` QSqlQuery::first()`, ` QSqlQuery::last()` und ` QSqlQuery::seek()` navigieren. Der aktuelle Zeilenindex wird von ` QSqlQuery::at()` zurückgegeben, und die Gesamtzahl der Zeilen im Ergebnissatz ist bei Datenbanken, die dies unterstützen, über ` QSqlQuery::size()` abrufbar.
Um festzustellen, ob ein Datenbanktreiber eine bestimmte Funktion unterstützt, verwenden Sie ` QSqlDriver::hasFeature()`. Im folgenden Beispiel rufen wir ` QSqlQuery::size()` auf, um die Größe einer Ergebnismenge zu ermitteln. Wenn die zugrunde liegende Datenbank diese Funktion unterstützt, wird die Größe zurückgegeben; andernfalls navigieren wir zum letzten Datensatz und ermitteln anhand der Position der Abfrage, wie viele Datensätze vorhanden sind.
QSqlQuery query;
int numRows;
query.exec("SELECT name, salary FROM employee WHERE salary > 50000");
QSqlDatabase defaultDB = QSqlDatabase::database();
if (defaultDB.driver()->hasFeature(QSqlDriver::QuerySize)) {
numRows = query.size();
} else {
// this can be very slow
query.last();
numRows = query.at() + 1;
}Wenn Sie innerhalb einer Ergebnismenge navigieren und next() sowie seek() ausschließlich zum Vorwärtsblättern verwenden, können Sie vor dem Aufruf von exec() die Funktion ` QSqlQuery::setForwardOnly()`(true) aufrufen. Dies ist eine einfache Optimierung, die die Abfrage bei der Verarbeitung großer Ergebnismengen erheblich beschleunigt.
Einfügen, Aktualisieren und Löschen von Datensätzen
QSqlQuery kann beliebige SQL-Anweisungen ausführen, nicht nur „ SELECT“-Anweisungen. Das folgende Beispiel fügt mithilfe von „ INSERT “ einen Datensatz in eine Tabelle ein:
QSqlQuery query;
query.exec("INSERT INTO employee (id, name, salary) "
"VALUES (1001, 'Thad Beaumont', 65000)");Wenn Sie viele Datensätze gleichzeitig einfügen möchten, ist es oft effizienter, die Abfrage von den tatsächlich einzufügenden Werten zu trennen. Dies kann mithilfe von Platzhaltern erfolgen. Qt unterstützt zwei Platzhalter-Syntaxen: benannte Bindung und positionelle Bindung. Hier ist ein Beispiel für benannte Bindung:
QSqlQuery query;
query.prepare("INSERT INTO employee (id, name, salary) "
"VALUES (:id, :name, :salary)");
query.bindValue(":id", 1001);
query.bindValue(":name", "Thad Beaumont");
query.bindValue(":salary", 65000);
query.exec();Hier ist ein Beispiel für die positionelle Bindung:
QSqlQuery query;
query.prepare("INSERT INTO employee (id, name, salary) "
"VALUES (?, ?, ?)");
query.addBindValue(1001);
query.addBindValue("Thad Beaumont");
query.addBindValue(65000);
query.exec();Beide Syntaxvarianten funktionieren mit allen von Qt bereitgestellten Datenbanktreibern. Wenn die Datenbank die Syntax nativ unterstützt, leitet Qt die Abfrage einfach an das DBMS weiter; andernfalls simuliert Qt die Platzhaltersyntax durch Vorverarbeitung der Abfrage. Die tatsächliche Abfrage, die letztendlich vom DBMS ausgeführt wird, ist über ` QSqlQuery::executedQuery()` verfügbar.
Beim Einfügen mehrerer Datensätze müssen Sie ` QSqlQuery::prepare()` nur einmal aufrufen. Anschließend rufen Sie ` bindValue()` oder ` addBindValue()` gefolgt von ` exec()` so oft wie nötig auf.
Neben der Leistung besteht ein Vorteil von Platzhaltern darin, dass Sie ganz einfach beliebige Werte angeben können, ohne sich Gedanken über das Escapen von Sonderzeichen machen zu müssen.
Das Aktualisieren eines Datensatzes erfolgt ähnlich wie das Einfügen in eine Tabelle:
QSqlQuery query;
query.exec("UPDATE employee SET salary = 70000 WHERE id = 1003");Sie können auch benannte oder positionelle Bindungen verwenden, um Parameter mit tatsächlichen Werten zu verknüpfen.
Abschließend noch ein Beispiel für eine ` DELETE `-Anweisung:
QSqlQuery query;
query.exec("DELETE FROM employee WHERE id = 1007");Transaktionen
Wenn die zugrunde liegende Datenbank-Engine Transaktionen unterstützt, gibt „ QSqlDriver::hasFeature “ (QSqlDriver::Transactions) den Wert „true“ zurück. Sie können „ QSqlDatabase::transaction()“ verwenden, um eine Transaktion zu starten, gefolgt von den SQL-Befehlen, die Sie im Rahmen der Transaktion ausführen möchten, und anschließend entweder „ QSqlDatabase::commit()“ oder „ QSqlDatabase::rollback()“. Bei der Verwendung von Transaktionen müssen Sie die Transaktion starten, bevor Sie Ihre Abfrage erstellen.
Beispiel:
QSqlDatabase::database().transaction();
QSqlQuery query;
query.exec("SELECT id FROM employee WHERE name = 'Torild Halvorsen'");
if (query.next()) {
int employeeId = query.value(0).toInt();
query.exec("INSERT INTO project (id, name, ownerid) "
"VALUES (201, 'Manhattan Project', "
+ QString::number(employeeId) + ')');
}
QSqlDatabase::database().commit();Transaktionen können verwendet werden, um sicherzustellen, dass ein komplexer Vorgang atomar ist (z. B. das Nachschlagen eines Fremdschlüssels und das Anlegen eines Datensatzes), oder um die Möglichkeit zu bieten, eine komplexe Änderung während der Ausführung abzubrechen.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.