C++Builder XE5でFireDACのTFDQueryを使ってデータを登録すると余計な文字が登録される。(解決済み)

C++Builder XE5でFireDACのTFDQueryを使ってデータを登録すると余計な文字が登録されます。
回避策をご存じでしたら教えてください。<(_ _)>

追記

FDQuery1->ParamByName("name")->AsWideString = "テスト1";

と、AsWideStringを使うことで正しく動作しました。

以下、本文。

実行環境について

次の環境で現象が起こっています。

  • Windows 8
  • RAD Studio XE5
  • Firebird 2.5.2 Embedded

問題の現象について

C++Builder XE5で次のコードで登録すると、「テスト1」の文字の後ろに余計な文字が登録されます。
Delphi XE5では問題は起こりません。

FDQuery1->SQL->Text = "insert into testtab(name) values(:name)";
FDQuery1->ParamByName("name")->AsString = "テスト1";
FDQuery1->ExecSQL();

FireDACモニタで見ると、次のように余計な文字が追加された状態で、Firebirdに送信されているようでした。
※ DireDACモニタの使い方については「FireDACでアプリケーションとデータベースの通信ログを取得する(1)FDMonitorに出力する」をご覧ください。

003

>> Form1.FDConnection1.Sent
     . Var [N=0, Name="NAME", Type=SQL_VARYING, Prec=0, Scale=0, Size=60, Data(0)='テスト1??攀']
<< Sent

検証用アプリケーション

検証用アプリケーションのプロジェクトはこちらからダウンロードできます。

VCLフォームアプリケーションを新規に作成して、フォームに次のコンポーネントを配置します。

  • TButton
  • TMemo
  • TFDConnection
  • TFDGUIxWaitCursor
  • TFDMoniRemoteClientLink
  • TFDPhysFBDriverLink
  • TFDQuery

002

Button1のOnClickイベントに次のコードを記述します。

#include <System.IOUtils.hpp>

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  //データベースファイルのパス
  UnicodeString dbfile = "C:\\test\\XXX.FDB";
  FDPhysFBDriverLink1->VendorLib = "C:\\driver\\fbembed.dll"; //Firebird ドライバの場所

  FDConnection1->LoginPrompt = false;
  FDConnection1->DriverName = "FB";
  FDConnection1->Params->Clear();
  FDConnection1->Params->Add("Database=" + dbfile);
  FDConnection1->Params->Add("User_Name=sysdba");
  FDConnection1->Params->Add("Password=masterkey");
  FDConnection1->Params->Add("MonitorBy=Remote");
  FDConnection1->Params->Add("CharacterSet=UNICODE_FSS");
  FDConnection1->Params->Add("CreateDatabase=Yes");
  FDConnection1->Params->Add("DriverID=FB");
  FDMoniRemoteClientLink1->Tracing = true;
  FDQuery1->Connection = FDConnection1;
  FDGUIxWaitCursor1->Provider = "Forms";

  //すでにファイルが存在するときは削除する
  if (TFile::Exists(dbfile)) TFile::Delete(dbfile);

  //データベースに接続する
  FDConnection1->Connected = true;

  //テーブルを作成する
  FDConnection1->ExecSQL("create table testtab (name varchar(20))");
  FDConnection1->Commit();

  //登録する
  FDQuery1->SQL->Text = "insert into testtab(name) values(:name)";
  FDQuery1->ParamByName("name")->AsString = "テスト1";
  FDQuery1->ExecSQL();

  //テーブルの内容を表示する
  FDQuery1->Open("select name from testtab");
  Memo1->Lines->Add(FDQuery1->FieldByName("name")->AsString);
  FDQuery1->Close();

  //データベースの接続を切断する
  FDConnection1->Connected = false;
}

001

解決策

FDQuery1->ParamByName("name")->AsWideString = "テスト1";

と、AsWideStringを使うことで正しく動作しました。

コメント

  1. データベースファイルなども含めたサンプルプロジェクト付きで、QualityCentralに登録をお願いします。
    なお、ソースファイルはUTF-8で保存するようにしてください。

  2. こんにちは。
    FDQuery1->ParamByName(“name”)->AsString = “テスト1”;
    ではなく
    FDQuery1->ParamByName(“name”)->AsWideString = L”テスト1″;
    ではどうでしょうか? (Lは不要だと思いますが)

  3. ありがとうございます。
    FDQuery1->ParamByName(“name”)->AsWideString = “テスト1”;
    で正しく登録できました。

  4. Delphi10 seattleで
    FireDACの配列DMLでデータを一括登録するときの、AsStringsでも同じ症状でした。
    AsWideStringsで解決できました。

    ありがとうございました。

コメントを残す

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

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