資料庫連接參數(Server、Database、User、Password)寫死在代碼中,導致部署環境切換、安全審計、密碼輪換極其痛苦。本文示範 Delphi 中將參數存入 **INI 檔**,並封裝為可復用單元(`RWini.pas`),實現讀寫分離、自動生成連接串、錯誤時彈出配置對話框的完整閉環。
| 關鍵字 | 含義 |
| Provider | OLE DB Provider 名稱(SQLOLEDB.1 / MSDAORA.1 / OraOLEDB.Oracle 等) |
| Data Source | 服務器網路地址或別名 |
| Initial Catalog | 資料庫名稱 |
| User ID / Password | 認證憑證 |
| Persist Security Info | True 允許屬性視圖顯示密碼,False 更安全 |
INI 檔規範設計
[dbParam]
Data Source=GTSERVER
Initial Catalog=SuperWorkFlow
User ID=map
Password=map
- Section 名用 `[ ]` 包裹,頂格書寫。
- Key=Value 格式,Key 頂格,等號緊跟 Key。
- 註解行以 `;` 開頭。
- 編碼建議 UTF-8 with BOM 或 ANSI(視 Delphi 版本)。
核心封裝單元:RWini.pas
unit RWini;
interface
uses
SysUtils, Classes, INIFiles;
const
STR_INI_NAME = 'db.ini'; // 相對於應用程式目錄
var
IniParam: TIniFile;
StrLocal: String;
procedure ReadParam(out Server, Database, User, Password: String);
procedure WriteParam(const Server, Database, User, Password: String);
function GetConnStr: String;
implementation
procedure ReadParam(out Server, Database, User, Password: String);
begin
Server := IniParam.ReadString('dbParam', 'Data Source', '');
Database := IniParam.ReadString('dbParam', 'Initial Catalog', '');
User := IniParam.ReadString('dbParam', 'User ID', '');
Password := IniParam.ReadString('dbParam', 'Password', '');
end;
procedure WriteParam(const Server, Database, User, Password: String);
begin
IniParam.WriteString('dbParam', 'Data Source', Server);
IniParam.WriteString('dbParam', 'Initial Catalog', Database);
IniParam.WriteString('dbParam', 'User ID', User);
IniParam.WriteString('dbParam', 'Password', Password);
end;
function GetConnStr: String;
var
Server, Database, User, Password: String;
begin
ReadParam(Server, Database, User, Password);
Result := 'Provider=SQLOLEDB.1;Password=' + Password +
';Persist Security Info=True;User ID=' + User +
';Initial Catalog=' + Database +
';Data Source=' + Server;
end;
initialization
GetDir(0, StrLocal); // 取得應用程式目錄
IniParam := TIniFile.Create(StrLocal + STR_INI_NAME);
finalization
IniParam.Free;
end.
資料模塊自動連接邏輯
procedure TDM.DataModuleCreate(Sender: TObject);
var
ConfForm: TConfForm;
begin
ADOConnection1.ConnectionString := RWini.GetConnStr;
try
ADOConnection1.Connected := True;
except
on E: EOleException do
begin
ConfForm := TConfForm.Create(Self);
try
ConfForm.ShowModal;
finally
ConfForm.Free;
end;
// 用戶配置後重試
ADOConnection1.ConnectionString := RWini.GetConnStr;
ADOConnection1.Connected := True;
end;
end;
end;
配置對話框:TConfForm
對話框包含 4 個 Edit(Server, Database, User, Password)+ OK/Cancel 按鈕。
procedure TConfForm.FormShow(Sender: TObject);
var
Srv, DB, Usr, Pwd: String;
begin
RWini.ReadParam(Srv, DB, Usr, Pwd);
edtServer.Text := Srv;
edtDatabase.Text := DB;
edtUser.Text := Usr;
edtPassword.Text := Pwd;
ActiveControl := btnOK;
end;
procedure TConfForm.btnOKClick(Sender: TObject);
begin
RWini.WriteParam(edtServer.Text, edtDatabase.Text, edtUser.Text, edtPassword.Text);
ModalResult := mrOK;
end;
procedure TConfForm.btnCancelClick(Sender: TObject);
begin
ModalResult := mrCancel;
end;
進階加固建議
| 風險 | 對策 |
| INI 明文密碼洩露 | 1. 部署時用 DPAPI/Windows Data Protection 加密 INI 2. 或改用 Registry 加密存儲 3. 生產環境採用 Windows Authentication (SSPI) 免密碼 |
| 多環境配置管理 | 建立 `db_dev.ini`、`db_test.ini`、`db_prod.ini`,啟動參數指定載入哪個 |
| 連接池與連接串不匹配 | ADO Connection `ConnectionString` 變更後必須 `Connected := False` 再 `True` 重建池 |
| 64 位 Delphi + 32 位 Provider | 編譯目標平台與 Provider 位數一致,或用 Microsoft OLE DB Driver for SQL Server (MSOLEDBSQL) 原生 64 位 |
現代化替代方案
- FireDAC (Delphi 10+ 內建):`TFDConnection.Params.LoadFromFile('db.ini')` 直接支援 INI/JSON/Registry,內建連接池、異步、加密、驅動自動發現。
- Spring4D / DSharp:依賴注入容器管理連接生命週期,配置來源可插拔(YAML/JSON/Environment Variables/Consul/Etcd)。
- Docker/K8s 部署:連接參數以 Environment Variables 或 Secrets 掛載,應用啟動時讀取環境變數構建連接串,完全去配置檔。
總結
「參數外部化 → 統一讀寫封裝 → 失敗友善引導配置」是 Delphi 資料庫應用移植性的基石。`RWini.pas` 模式簡單可靠,適合中小型專案快速落地;大型/雲原生專案建議升級 FireDAC + 環境變數/密鑰管理體系,實現「零配置檔、全環境一致、安全合規」。
- 上一篇文章: DAN (Database Area Network) 架構深度解析:超越 SAN 的動態資料庫負載均衡
- 下一篇文章: Oracle Heterogeneous Services 實戰:透過 ODBC 實現 Oracle 與 SQL Server 實時互訪
Copyright ©
程式碼之家 All Rights Reserved