SQL文の実行
QSqlQuery クラスは、SQL文を実行し、クエリの結果セットをナビゲートするためのインターフェースを提供します。
次のセクションで説明するQSqlQueryModel クラスおよびQSqlTableModel クラスは、データベースにアクセスするためのより高レベルのインターフェースを提供します。SQLに不慣れな場合は、次のセクション(「SQLモデルクラスの使用」)に直接進むことをお勧めします。
クエリの実行
SQL文を実行するには、QSqlQuery オブジェクトを作成し、次のようにQSqlQuery::exec()を呼び出すだけです:
QSqlQuery query;
query.exec("SELECT name, salary FROM employee WHERE salary > 50000");QSqlQuery のコンストラクタは、使用するデータベース接続を指定するQSqlDatabase オブジェクトをオプションで受け取ります。上記の例では、接続を指定していないため、デフォルトの接続が使用されます。
エラーが発生した場合、exec()はfalse を返します。そのエラーは、QSqlQuery::lastError()として参照できます。
結果セットの操作
QSqlQuery これにより、結果セットに1レコードずつアクセスできます。exec()を呼び出した後、QSqlQuery の内部ポインタは最初のレコードの1つ前の位置に設定されます。 最初のレコードに進むには、QSqlQuery::next()を1回呼び出し、その後、false が返されるまで、next()を繰り返し呼び出して他のレコードにアクセスする必要があります。以下は、すべてのレコードを順に反復処理する典型的なループです:
while(query.next()) {
QString name=query.value(0).toString();
intsalary=query.value(1).toInt();
qDebug() << name << salary;
}QSqlQuery::value() 関数は、現在のレコード内のフィールドの値を返します。 フィールドは0を起点とするインデックスで指定されます。QSqlQuery::value()は、QVariant を返します。これは、int 、QString 、QByteArray など、さまざまなC++およびQt Coreデータ型を格納できる型です。異なるデータベース型は、自動的に最も近いQtの等価型にマッピングされます。コードスニペットでは、QVariant::toString()およびQVariant::toInt()を呼び出して、variantをQString およびint に変換しています。
Qtがサポートするデータベースで使用が推奨される型の概要については、こちらの表を参照してください。
データセット内を移動するには、QSqlQuery::next()、QSqlQuery::previous()、QSqlQuery::first()、QSqlQuery::last()、およびQSqlQuery::seek() を使用できます。現在の行インデックスはQSqlQuery::at() によって返され、結果セットの総行数は、それをサポートするデータベースにおいてQSqlQuery::size() で取得可能です。
データベースドライバが特定の機能をサポートしているかどうかを確認するには、QSqlDriver::hasFeature() を使用します。次の例では、QSqlQuery::size() を呼び出して、基となるデータベースの結果セットのサイズがその機能をサポートしているかどうかを確認しています。サポートされていない場合は、最後のレコードに移動し、クエリの位置からレコードの総数を判断します。
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;
}結果セット内で移動し、next() および seek() を前方への閲覧にのみ使用する場合は、exec() を呼び出す前にQSqlQuery::setForwardOnly() (true) を呼び出すことができます。これは簡単な最適化手法であり、大規模な結果セットを処理する際にクエリの実行速度を大幅に向上させることができます。
レコードの挿入、更新、削除
QSqlQuery は、SELECTだけでなく、任意のSQL文を実行できます。次の例では、INSERT を使用してテーブルにレコードを挿入しています:
QSqlQuery query;
query.exec("INSERT INTO employee (id, name, salary) "
"VALUES (1001, 'Thad Beaumont', 65000)");一度に多数のレコードを挿入したい場合、クエリと実際に挿入する値を分離した方が効率的なことがよくあります。これはプレースホルダーを使用することで実現できます。Qtでは、名前付きバインディングと位置指定バインディングという2つのプレースホルダー構文をサポートしています。以下に、名前付きバインディングの例を示します:
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();以下は位置指定バインディングの例です:
QSqlQuery query;
query.prepare("INSERT INTO employee (id, name, salary) "
"VALUES (?, ?, ?)");
query.addBindValue(1001);
query.addBindValue("Thad Beaumont");
query.addBindValue(65000);
query.exec();どちらの構文も、Qtが提供するすべてのデータベースドライバで動作します。データベースが当該構文をネイティブでサポートしている場合、Qtは単にクエリをDBMSに転送します。そうでない場合、Qtはクエリを前処理することでプレースホルダー構文をシミュレートします。最終的にDBMSによって実行される実際のクエリは、QSqlQuery::executedQuery() として取得できます。
複数のレコードを挿入する場合、QSqlQuery::prepare() を 1 回呼び出すだけで済みます。その後、bindValue() またはaddBindValue() を呼び出し、必要に応じてexec() を何度でも続けて呼び出します。
パフォーマンスの面以外にも、プレースホルダーの利点として、特殊文字のエスケープを気にすることなく、任意の値を簡単に指定できることが挙げられます。
レコードの更新は、テーブルへの挿入と同様です:
QSqlQuery query;
query.exec("UPDATE employee SET salary = 70000 WHERE id = 1003");また、名前付きバインディングや位置指定バインディングを使用して、パラメータを実際の値に関連付けることもできます。
最後に、DELETE 文の例を以下に示します:
QSqlQuery query;
query.exec("DELETE FROM employee WHERE id = 1007");トランザクション
基盤となるデータベースエンジンがトランザクションをサポートしている場合、QSqlDriver::hasFeature(QSqlDriver::Transactions) は true を返します。QSqlDatabase::transaction() を使用してトランザクションを開始し、そのトランザクションのコンテキスト内で実行したい SQL コマンドを記述した後、QSqlDatabase::commit() またはQSqlDatabase::rollback() のいずれかを実行します。トランザクションを使用する場合は、クエリを作成する前にトランザクションを開始する必要があります。
例:
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();トランザクションを使用すると、複雑な操作(たとえば、外部キーの検索とレコードの作成など)の原子性を確保したり、複雑な変更を途中でキャンセルしたりすることができます。
© 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.