FireDAC 下的 SQLite 開發積累了大量實戰技巧。本文作為系列收尾,彙整多資料庫附掛查詢、OnAuthorize/OnUpdate 回調、TFDMemTable 替代 TClientDataSet、R-Tree 行快速定位、並發鎖定模式等高頻用法,供快速查閱。
// 主連接已開啟
FDConnection1.ExecSQL('ATTACH ''C:\Data\hr.sdb'' AS hr');
FDConnection1.ExecSQL('ATTACH ''C:\Data\cust.sdb'' AS cust');
FDQuery1.Open('SELECT * FROM "Orders" o ' +
'LEFT JOIN hr."Employees" e ON o.EmployeeID = e.EmployeeID ' +
'LEFT JOIN cust."Customers" c ON o.CustomerID = c.CustomerID');
附掛後可跨庫 JOIN,極適合「主業務庫 + 字典/歷史庫」架構。
procedure TForm1.FormCreate(Sender: TObject);
begin
FDConnection1.Connected := True;
TSQLiteDatabase(FDConnection1.ConnectionIntf.CliObj).OnAuthorize := DoAuthorize;
FDQuery1.Open;
end;
procedure TForm1.DoAuthorize(ADB: TSQLiteDatabase; ACode: Integer;
const AArg1, AArg2, AArg3, AArg4: String; var AResult: Integer);
begin
Memo1.Lines.Add(Format('%d - %s - %s - %s - %s', [ACode, AArg1, AArg2, AArg3, AArg4]));
// ACode = SQLITE_DELETE (9) 時攔截刪除
if ACode = SQLITE_DELETE then AResult := SQLITE_DENY else AResult := SQLITE_OK;
end;
ACode 對應 SQLite 操作碼:SQLITE_SELECT(21), SQLITE_INSERT(18), SQLITE_UPDATE(23), SQLITE_DELETE(9) 等。可實現細粒度權限控制。
procedure TForm1.FormCreate(Sender: TObject);
begin
FDConnection1.Connected := True;
TSQLiteDatabase(FDConnection1.ConnectionIntf.CliObj).OnUpdate := DoUpdate;
FDQuery1.Open;
end;
procedure TForm1.DoUpdate(ADB: TSQLiteDatabase; AOper: Integer;
const ADatabase, ATable: String; ARowid: sqlite3_int64);
begin
Memo1.Lines.Add(Format('Oper:%d DB:%s Table:%s RowID:%d', [AOper, ADatabase, ATable, ARowid]));
// AOper: 1=INSERT, 2=DELETE, 3=UPDATE
// 可觸發 UI 刷新、同步其他庫、寫入審計日誌
end;
// 直接按 ROWID 查詢,極快(O(1))
FDQuery1.Open('SELECT * FROM Orders WHERE ROWID = :RID', [12345]);
輕量、無外部依賴、支援索引/過濾/排序/JSON 序列化,完美替代笨重的 TClientDataSet。
procedure TForm1.FormCreate(Sender: TObject);
begin
with FDMemTable1.FieldDefs.AddFieldDef do begin Name := 'word'; DataType := ftString; Size := 50; end;
with FDMemTable1.FieldDefs.AddFieldDef do begin Name := 'ph'; DataType := ftString; Size := 50; end;
with FDMemTable1.FieldDefs.AddFieldDef do begin Name := 'note'; DataType := ftString; Size := 255; end;
with FDMemTable1.FieldDefs.AddFieldDef do begin Name := 'num'; DataType := ftInteger; end;
FDMemTable1.IndexDefs.Add('Index_1', 'word', [ixPrimary]);
FDMemTable1.CreateDataSet;
end;
SQLite 預設 SERIALIZED 鎖定模式(單寫多讀)。高並發寫入場景可調整:
PRAGMA locking_mode = EXCLUSIVE:獨占模式,寫入效能最高,但完全阻塞讀取。PRAGMA journal_mode = WAL (Write-Ahead Logging):讀寫不阻塞,極大提升並發吞吐,FireDAC 預設已啟用。LockingMode=Normal/Exclusive, JournalMode=WAL/DELETE/OFF。詳細文檔:FireDAC SQLite 並發指南
FireDAC + SQLite 組合功能強大且輕量,掌握上述進階特性可應對多數嵌入式/桌面/輕量級服務端儲存需求。系列文章至此告一段落,後續將轉向 IntraWeb 網頁開發領域。