「A simple Delphi wrapper for Sqlite 3 « Tim Anderson’s ITWriting」でDelphi用SQLiteライブラリが公開されている。
このライブラリの導入方法と簡単な使い方を以前の記事(C++Builder XEでDelphi用SQLiteライブラリを使う。その2)で紹介した。
前回の記事(「C++Builder XEでDelphi用SQLiteライブラリを使う。その3(PrepareSQLその1)」)では、BindSQLを使う方法を紹介した。
今回は名前付きのパラメータを使用できるAddParamText()やAddParamInt()を使う方法を紹介する。
次の手順で実行する。
- AddParamText()やAddParamInt()でパラメータ名と値を登録する。
db->AddParamText(L":name", L"あいうえお"); db->AddParamInt(L":val", 666);
- GetUniTable()でSQLの実行結果を取得する
UnicodeString sql = L"SELECT name,val FROM test WHERE name=:name OR val=:val"; std::unique_ptr<TSQLiteUniTable> table(db->GetUniTable(sql));
- 実行結果を使用する
boost::wformat fmter(L"name: %s, val: %d"); while (true) { if (table->Eof) break; UnicodeString name = table->FieldAsString(table->FieldIndex["name"]); int val = table->FieldAsInteger(table->FieldIndex["val"]); std::wcout << fmter % name.c_str() % val << std::endl; table->Next(); }
サンプルプログラム
std::unique_ptr<TSQLiteDatabase> db(new TSQLiteDatabase("test.db"));
db->ExecSQL("CREATE TABLE test (name TEXT, val INTEGER);"); //テーブルを作成
db->ExecSQL("INSERT INTO test (name,val) VALUES (\"あいうえお\",555);");
db->ExecSQL("INSERT INTO test (name,val) VALUES (\"かきくけこ\",666);");
db->ExecSQL("INSERT INTO test (name,val) VALUES (\"さしすせそ\",777);");
//パラメータ名と値を登録する
db->AddParamText(L":name", L"あいうえお");
db->AddParamInt(L":val", 666);
//SQLを実行する
UnicodeString sql = L"SELECT name,val FROM test WHERE name=:name OR val=:val";
std::unique_ptr<TSQLiteUniTable> table(db->GetUniTable(sql));
//結果を表示する
boost::wformat fmter(L"name: %s, val: %d");
while (true)
{
if (table->Eof) break;
UnicodeString name = table->FieldAsString(table->FieldIndex["name"]);
int val = table->FieldAsInteger(table->FieldIndex["val"]);
std::wcout << fmter % name.c_str() % val << std::endl;
table->Next();
}
なぜか文字化けが発生したので、ソースコードを修正した。
修正箇所
procedure TSQLiteDatabase.SetParams(Stmt: TSQLiteStmt);
(省略)
SQLITE_TEXT:
// sqlite3_bind_text16(Stmt, i, PChar(par.valuedata),
// length(par.valuedata), SQLITE_TRANSIENT);
sqlite3_bind_text(Stmt, i, PAnsiChar(UTF8String(par.valuedata)),
length(UTF8String(par.valuedata)), SQLITE_TRANSIENT);
元のコードではUTF-16文字列を使用する関数を使っていたが、UTF-8文字列を使う関数を使用するように変更している。
なぜ元のコードで文字化けが発生したのかわからないが、この変更で問題なく動作しているようだ。
Pingback: C++Builder XEでDelphi用SQLiteライブラリを使う。まとめ « 山本隆の開発日誌