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に出力する」をご覧ください。
>> 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
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;
}
解決策
FDQuery1->ParamByName("name")->AsWideString = "テスト1";
と、AsWideStringを使うことで正しく動作しました。
データベースファイルなども含めたサンプルプロジェクト付きで、QualityCentralに登録をお願いします。
なお、ソースファイルはUTF-8で保存するようにしてください。
こんにちは。
FDQuery1->ParamByName(“name”)->AsString = “テスト1”;
ではなく
FDQuery1->ParamByName(“name”)->AsWideString = L”テスト1″;
ではどうでしょうか? (Lは不要だと思いますが)
ありがとうございます。
FDQuery1->ParamByName(“name”)->AsWideString = “テスト1”;
で正しく登録できました。
Delphi10 seattleで
FireDACの配列DMLでデータを一括登録するときの、AsStringsでも同じ症状でした。
AsWideStringsで解決できました。
ありがとうございました。