1

私のアプリには、TFDConnection別のデータベース (タイプ) に接続するときに再利用されるデザインタイムがあります。
また、その設定からプールされた接続を導出し、FDManager.AddConnectionDefマルチスレッド時に使用するためにこれを登録します (ここのように)。

これを 2 回目に設定したときにAddConnectionDef、同じ ConnectionDefName で誤って再度呼び出しました。ドキュメントには次のように記載されています。

この名前は、ConnectionDefs リスト内の他の接続定義全体で一意である必要があり、そうでない場合は例外が発生します。

これは起こりません。例外は発生しません。同じ名前の 2 つの ConnectionDefs が発生するだけです。
興味のある方のために: 次のコード ブロックは、この動作を示しています ( Quality Portal の RSP-19107 )。これは私の当面の問題ではありませDeleteConnectionDef
しかし、それもうまくいかないことがわかりまし。2 番目のコード ブロックを参照してください。

procedure TFrmFireDACConnectionNames.BtnBug1Click(Sender: TObject);
var
   lParams: TStringList;
   i,l    : integer;
begin
   lParams := TStringList.Create;
   lParams.Add('User_Name=sysdba');
   lParams.Add('Password=masterkey');
   lParams.Add('database=D:\Testing\test.gdb');
   lParams.Add('Server=localhost');
   lParams.Add('Pooled=true');
   lParams.Add('DriverID=FB');
   FDManager.AddConnectionDef('FBPooled','FB',lParams);
   lParams.Values['database'] := 'D:\Testing\test2.gdb';
   FDManager.AddConnectionDef('FBPooled','FB',lParams);

   // This shows the two identical ConnectionDefs (inspect lParams):
   lParams.Clear;
   l := FDManager.ConnectionDefs.Count;
   for i := 0 to l-1 do
      lParams.Add(FDManager.ConnectionDefs[i].Name);
   // Contents on my machine:
   // Access_Demo
   // Access_Demo_Pooled
   // DBDEMOS
   // EMPOYEE
   // MSSQL_Demo
   // RBDemos
   // SQLite_Demo
   // SQLite_Demo_Pooled
   // FBPooled           <== Duplicates
   // FBPooled

   // To check that the two added have their respective Params, inspect lParams with breakpoints on the lines below:
   lParams.Assign(FDManager.ConnectionDefs[l-1].Params);
   // Contents on my machine:
   // User_Name=sysdba
   // Password=masterkey
   // database=D:\Testing\test2.gdb
   // Server=localhost
   // Pooled=true
   // DriverID=FB
   // Name=FBPooled

   lParams.Assign(FDManager.ConnectionDefs[l-2].Params);
   // Contents on my machine:
   // User_Name=sysdba
   // Password=masterkey
   // database=D:\Testing\test.gdb
   // Server=localhost
   // Pooled=true
   // DriverID=FB
   // Name=FBPooled

   lParams.Free;
end;

以下は、DeleteConnectionDef失敗を示すサンプル コードです。を使用したり、開いたりしないことに注意してくださいTFDConnection

procedure TFrmFireDACConnectionNames.BtnDeleteTestClick(Sender: TObject);
var
   lParams  : TStringList;
   i,l      : integer;
   lConnName: String;
begin
   lParams := TStringList.Create;
   lConnName := 'MyConnPooled';

   lParams.Add('DriverID=FB');
   lParams.Add('User_Name=sysdba');
   lParams.Add('Password=masterkey');
   lParams.Add('Database=d:\Testing\Diverse\FireDACConnectionNames\test.gdb');
   lParams.Add('Server=localhost');
   lParams.Add('Pooled=true');

   FDManager.AddConnectionDef(lConnName,'FB',lParams);

   lParams.Clear;
   lParams.Add('DriverID=MSSQL');
   lParams.Add('User_Name=test');
   lParams.Add('Password=test');
   lParams.Add('Database=test');
   lParams.Add('Server=VS20032008');
   lParams.Add('Pooled=true');

   for l := FDManager.ConnectionDefs.Count-1 downto 0 do
      if FDManager.ConnectionDefs[l].Name = lConnName then
      begin
         FDManager.DeleteConnectionDef(lConnName);     // This gets executed
         Break;
      end;
   FDManager.AddConnectionDef(lConnName,'MSSQL',lParams);

   // Check ConnectionDefs (inspect lParams):
   lParams.Clear;
   l := FDManager.ConnectionDefs.Count;
   for i := 0 to l-1 do
      lParams.Add(FDManager.ConnectionDefs[i].Name);
   // Contents on my machine:
   // Access_Demo
   // Access_Demo_Pooled
   // DBDEMOS
   // EMPLOYEE
   // MSSQL_Demo
   // RBDemos
   // SQLite_Demo
   // SQLite_Demo_Pooled
   // MyConnPooled      <== Still duplicate
   // MyConnPooled
   lParams.Free;
end;

では、ここで何が起こっているのでしょうか?どうすれば修正できますか?

これは Delphi Tokyo 10.2.1
です。このコードを実行するには、フォームにTFDPhysFBDriverLinkandTFDPhysMSSQLDriverLinkを配置します。それらに対して .Release を呼び出してみましたが、役に立ちませんでした。


修正: コードを実行するために TFDPhysxxxDriverLink コンポーネントを配置する必要はありません。関連するユニットの存在は AddConnectionDefinition バグにとって不可欠であるため、文を残しています (承認された回答を参照)。


問題解決:FireDAC.Stan.Def.pasおよびのパッチはFireDAC.Comp.Client.pas、そのRSP-19107リンクから入手できます。

4

1 に答える 1