C++でSQLクエリを実行するには、データベース接続ライブラリやORM(Object-Relational Mapping)フレームワークを利用するのが一般的です。これらのツールは、特定のDBMS(データベース管理システム)と連携するためのインターフェースを提供します。
ODBCによるSQL実行
ODBC(Open Database Connectivity)は、アプリケーションがさまざまなリレーショナルデータベースに標準化された方法でアクセスできるようにするAPI仕様です。C++では、sql.hやsqlext.hといったヘッダをインクルードし、ODBC関数を使って接続・クエリ実行・結果処理を行います。
#include <sql.h>
#include <sqlext.h>
int main() {
SQLHENV env;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLRETURN rc;
// 環境ハンドル作成
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
// 接続ハンドル作成と接続
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
rc = SQLDriverConnect(dbc, nullptr,
(SQLCHAR*)"DRIVER={ODBC Driver 17 for SQL Server};"
"SERVER=localhost;DATABASE=testdb;UID=user;PWD=pass;",
SQL_NTS, nullptr, 0, nullptr, SQL_DRIVER_COMPLETE);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) return -1;
// ステートメントハンドル作成とクエリ実行
SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
SQLExecDirect(stmt, (SQLCHAR*)"SELECT product_name FROM products", SQL_NTS);
// 結果の取得
char buffer[256];
while (SQLFetch(stmt) == SQL_SUCCESS) {
SQLGetData(stmt, 1, SQL_C_CHAR, buffer, sizeof(buffer), nullptr);
// buffer の内容を処理
}
// リソース解放
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
SQLDisconnect(dbc);
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
return 0;
}
データベース固有のC++ライブラリの利用
多くのDBMSは、ODBCよりも高レベルなC++用クライアントライブラリを提供しています。たとえば、MySQL Connector/C++はC++ネイティブなインターフェースでMySQLとやり取りできます。
#include <mysql_driver.h>
#include <cppconn/connection.h>
#include <cppconn/statement.h>
#include <cppconn/resultset.h>
int main() {
auto driver = get_driver_instance();
std::unique_ptr<sql::Connection> conn(driver->connect("tcp://127.0.0.1:3306/testdb", "user", "pass"));
std::unique_ptr<sql::Statement> stmt(conn->createStatement());
std::unique_ptr<sql::ResultSet> res(stmt->executeQuery("SELECT name FROM employees"));
while (res->next()) {
// res->getString("name") で値を取得
}
return 0;
}
ORMフレームワークの活用
SOCIなどのORMライブラリを使うと、SQLを文字列として直接記述せずに、C++オブジェクトを通じてデータベース操作が可能です。これにより、型安全性やコードの可読性が向上します。
#include <soci/soci.h>
#include <soci/mysql/soci-mysql.h>
int main() {
soci::session db(soci::mysql, "host=localhost;dbname=testdb;user=user;password=pass");
std::string title;
int id = 101;
db << "SELECT book_title FROM books WHERE book_id = :id",
soci::use(id), soci::into(title);
// title に結果が格納される
return 0;
}
ODBCとJDBCの概要とC++における役割
ODBCはマイクロソフトが提唱した、プラットフォームおよび言語に依存しないデータベース接続の標準です。C++アプリケーションはODBCドライバ経由で任意の対応DBMS(PostgreSQL、SQL Server、Oracleなど)に接続できます。ODBCは低レベルな制御が可能ですが、コードが冗長になりがちです。
JDBC(Java Database Connectivity)はJava向けの標準データベース接続APIであり、C++からは直接使用できません。ただし、JDBCの設計思想(ドライバマネージャ、ステートメント、結果セットなど)はODBCにも影響を与えており、両者は概念的に類似しています。
C++でのデータベースプログラミングにおいては、ODBCが最も汎用的な選択肢です。一方、パフォーマンスや開発効率を重視する場合は、データベース固有のC++ライブラリやSOCIのようなORMを採用することが多いです。選択は、プロジェクトの要件(移植性、保守性、実行速度など)に基づいて判断すべきです。