前回までの話
再度挑戦
2話目において実践した、MySQL Connector C++を利用して
テーブル操作を行いたいです。
再度、ボタンを押した際のソース掲示。
void CMySQLTest1Dlg::OnBnClickedButton1()
{
sql::SQLString strHost = "tcp://127.0.0.1:3306"; // ホスト名
sql::SQLString strUser = "root"; // ユーザ名
sql::SQLString strPass = "password"; // パスワード
// ※パスワードは、前回設定したものを入れる
try
{
// MySQLドライバのインスタンス取得
sql::mysql::MySQL_Driver* driver = sql::mysql::get_mysql_driver_instance();
// DB接続情報を設定。
std::unique_ptr<sql::Connection> con(driver->connect(strHost, strUser, strPass));
//ここまで来たら、接続できた
AfxMessageBox(_T("接続成功"));
}
catch (sql::SQLException& e)
{
// 接続できなかった
CString errorMessage = _T("");
errorMessage.Format(_T("エラー: %s\r\nエラーコード: %d"), CString(e.what()), e.getErrorCode());
AfxMessageBox(errorMessage, MB_OK | MB_ICONERROR);
}
}try文の、接続成功メッセージ以降を追加していきます。
void CMySQLTest1Dlg::OnBnClickedButton1()
{
sql::SQLString strHost = "tcp://127.0.0.1:3306"; // ホスト名
sql::SQLString strUser = "root"; // ユーザ名
sql::SQLString strPass = "password"; // パスワード
// ※パスワードは、前回設定したものを入れる
try
{
// MySQLドライバのインスタンス取得
sql::mysql::MySQL_Driver* driver = sql::mysql::get_mysql_driver_instance();
//sql::SQLString strOpt = "SET NAMES utf8mb4";
// DB接続情報を設定。
std::unique_ptr<sql::Connection> con(driver->connect(strHost, strUser, strPass));
//ここまで来たら、接続できた
//AfxMessageBox(_T("接続成功"));
//con->setClientOption("OPT_CHARSET_NAME", "utf8mb4"); // これでクライアント側の文字セットを設定
// スキーマを設定
con->setSchema("testschema1");
// クエリを実行
std::unique_ptr<sql::PreparedStatement> pstmt(con->prepareStatement("SELECT name FROM testtable1 WHERE id = ?"));
pstmt->setInt(1, 1);
std::unique_ptr<sql::ResultSet> res(pstmt->executeQuery());
CString strDisp = _T(""); // 表示用
// 結果を処理
if (res->next())
{
do
{
std::string name = res->getString("name");
// UTF-8からUTF-16への変換
int len = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), -1, NULL, 0);
if (len > 0)
{
std::wstring wideName(len, 0);
MultiByteToWideChar(CP_UTF8, 0, name.c_str(), -1, &wideName[0], len);
// std::wstringからCStringに変換
CString cstrName(wideName.c_str());
strDisp += cstrName;
strDisp += _T("\r\n");
}
else
{
strDisp =_T("UTF - 8からUTF - 16への変換に失敗しました。");
break;
}
} while (res->next());
}
else
{
strDisp = _T("idが1のデータが見つかりませんでした。");
}
AfxMessageBox(strDisp, MB_OK | MB_ICONINFORMATION);
}
catch (sql::SQLException& e)
{
// 接続できなかった
CString errorMessage = _T("");
errorMessage.Format(_T("エラー: %s\r\nエラーコード: %d"), CString(e.what()), e.getErrorCode());
AfxMessageBox(errorMessage, MB_OK | MB_ICONERROR);
}
}17行目でスキーマを設定、20と21行目でSQL文を発行、23行目で実行です。
後は文字化けしないよう処理を加えて、cstrNameを表示させます。
処理実行
前回成功したとき同様、リリースモードでビルドします。
今のテーブルはこんな感じです。

ソースに書いたSQL文は以下と同じです。
SELECT name FROM testtable1 WHERE id = 1;出来上がったexe上のボタンを押すと。

やっと…できた…!
長かった(;´∀`)
他にも試す
ソース上のSQLを変えてみます。
ボタンやエディットボックス増やして色んなパターンを試す方もいいですが、
コントロール増やすの面倒なので()、
今回はソースを変更します。
SELECT name FROM testtable1 WHERE age = 20;
SQL発行の箇所を変更します。
// クエリを実行
std::unique_ptr<sql::PreparedStatement> pstmt(con->prepareStatement("SELECT name FROM testtable1 WHERE age = ?"));
pstmt->setInt(1, 20);age列が20は、id=1とid=11がいますが、果たして

良さげ。
INSERT 文
INSERTを行います。
// クエリを実行
std::unique_ptr<sql::PreparedStatement> pstmt(con->prepareStatement("INSERT INTO testtable1 VALUES (?, ?, ?)"));
pstmt->setInt(1, 25);
pstmt->setString(2, "Mike Davis");
pstmt->setInt(3, 70);
//std::unique_ptr<sql::ResultSet> res(pstmt->executeQuery());
pstmt->executeUpdate();
/*
CString strDisp = _T(""); // 表示用
// 結果を処理
if (res->next())
{
// 略
}
else
{
// 略
}
*/調べていて少し意外だったのが、name列にシングルクォーテーションは必要ないみたいです。
寧ろ、シングルクォーテーションがあるとエラーが出てきてしまいました。
そして7行目の代わりに8行目を使います。
executeQueryは通常、データの取得 (SELECT文) に使用され、
executeUpdateはデータの変更 (INSERT, UPDATE, DELETE 文) に使用されます。
ビルドしてボタンを押し、テーブルを見に行くと

反映されました。
因みに、名前に全角文字を使用した場合、エラーが出てきます。

SELECTのとき同様、UTF16⇔UTF8変換をすれば行けそうな気がしますが、
ちょっと力尽きてしまい、今回は断念します。
これは課題ということで。
DELETE文
INSERTができればDELETEも問題なくできるでしょうけど。
// クエリを実行
std::unique_ptr<sql::PreparedStatement> pstmt(con->prepareStatement("DELETE FROM testtable1 WHERE id = ?"));
pstmt->setInt(1, 11);
pstmt->executeUpdate();id=11の行を削除します。
ビルド、実行すると

削除確認できました。
さらば、律ちゃん。
終わりに
MySQL Connector C++を使って、MySQLのテーブル操作を行う話でした。
正直ここまでできるとは思ってなかったし、
課題たくさん出てきたけど、ちょっとずつ理解を深めたいです。
少しずつだけど、できることが多くなって少し嬉しいです。
今回はここまで。

コメント