C++Builder XEでDelphi用SQLiteライブラリを使う。その4(PrepareSQLその2)

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()を使う方法を紹介する。

次の手順で実行する。

  1. AddParamText()やAddParamInt()でパラメータ名と値を登録する。
    db->AddParamText(L":name", L"あいうえお");
    db->AddParamInt(L":val", 666);
    
  2. GetUniTable()でSQLの実行結果を取得する
    UnicodeString sql = L"SELECT name,val FROM test WHERE name=:name OR val=:val";
    std::unique_ptr<TSQLiteUniTable> table(db->GetUniTable(sql));
    
  3. 実行結果を使用する
    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文字列を使う関数を使用するように変更している。

なぜ元のコードで文字化けが発生したのかわからないが、この変更で問題なく動作しているようだ。

コメント

  1. Pingback: C++Builder XEでDelphi用SQLiteライブラリを使う。まとめ « 山本隆の開発日誌

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください