本文承接系列第一篇,著重解決「客戶端如何獲取伺服器端 BDE 資料庫別名」問題。通過在伺服器端佈署 TSession/TDatabase 管理連線,並在 COM 類型庫中新增 GetDatabaseNames/SetDatabaseName 兩個方法,實現別名列表下發與客戶端指定別名連線的雙向交互。
AutoSessionName=True、SessionName='Session1_4'、KeepConnection=True、Active=True。AliasName 指向具體 BDE 別名(如 Mymdb)、DatabaseName='a'(自訂邏輯名)、SessionName='Session1_4'、LoginPrompt=False。DatabaseName='a'、SessionName='Session1_4'、基礎 SQL select * from 獎金、Active=True。在 Type Library 編輯器中對介面 IPcSQL 新增:
OleVariant(陣列),供客戶端填充 ComboBox。[in] BSTR 參數(DBName, UserName, PassWord),客戶端指定別名與認證資訊。注意:方法名拼寫必須一致(範例中曾誤寫為 SetDatabaseNames 導致調用失敗)。
uses Variants; { VarArrayCreate 需要 }
function TPcSQL.GetDatabaseNames: OleVariant;
var I: Integer; DBNames: TStrings;
begin
DBNames := TStringList.Create;
try
Session1.GetDatabaseNames(DBNames); { 取得所有 BDE 別名 }
Result := VarArrayCreate([0, DBNames.Count-1], varOleStr); { 建立 OLE 相容陣列 }
for I := 0 to DBNames.Count-1 do Result[I] := DBNames[I];
finally DBNames.Free; end;
end;
procedure TPcSQL.SetDatabaseName(const DBName, UserName, PassWord: WideString);
begin
try
Database1.Close;
Database1.AliasName := DBName;
if (UserName<>'') and (PassWord<>'') then
begin
Database1.Params.Values['PASSWORD'] := PassWord;
Database1.Params.Values['USER NAME'] := UserName;
end;
Database1.Open;
except
on E: EDBEngineError do
raise Exception.Create('PassWord Required'); { 傳遞給客戶端觸發輸入對話框 }
end;
end;
VarArrayCreate(..., varOleStr) 確保字串陣列可跨 DCOM 邊界封送。Session.GetDatabaseNames 枚舉當前 BDE 所有別名。EDBEngineError 並拋出自定義例外,客戶端捕獲後彈出認證對話框重試。RemoteDataModule 實例,隔離性良好。