首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 防止關鍵欄位重複輸入:Table.BeforePost 事件中以 FindKey 即時檢查唯一性

     編輯:Delphi

資料庫編程中,確保關鍵欄位 (如員工編號、身分證號) 唯一性是基本需求。本文示範在 TTable.BeforePost 事件中,建立第二個 TTable 實例以 FindKey 快速查詢,若鍵值已存在則 Abort 取消寫入並彈出警告,保證資料完整性。

場景設定

  • 資料表:Renshi.dbf (dBASE/Paradox)
  • 關鍵欄位:Bianhao (編號,字串型),已建立索引
  • 介面:DBEdit1 綁定 Bianhao,DBEdit2 綁定 Xingming

核心程式碼:Table1.BeforePost


procedure TForm1.Table1BeforePost(DataSet: TDataSet);
var
  CheckTable: TTable;
begin
  CheckTable := TTable.Create(Self);
  try
    CheckTable.DatabaseName := 'C:\';
    CheckTable.TableName := 'Renshi.dbf';
    CheckTable.IndexFieldNames := 'Bianhao'; // 使用索引加速
    CheckTable.Open;

    CheckTable.SetKey;
    CheckTable.FieldByName('Bianhao').AsString := DBEdit1.Text;
    if CheckTable.GotoKey then // 找到重複鍵值
    begin
      ShowMessage('輸入的編號已存在!請重新輸入');
      Abort; // 取消 Post,資料不寫入
    end;
  finally
    CheckTable.Free;
  end;
end;

關鍵點解析

  1. 獨立 TTable 實例:避免干擾主 DataSet 的游標狀態與編輯模式。
  2. IndexFieldNames:指定索引欄位,GotoKey 走 B-tree 查找,極快 (O(log n))。
  3. SetKey / GotoKey:標準尋找鍵值流程,GotoKey 回傳 True 表示找到。
  4. Abort:在 BeforePost 中呼叫 Abort 會拋出 EAbort 例外,VCL 捕獲後取消寫入並保持編輯狀態,使用者可修正後再存。

替代方案比較

方案優點缺點
資料庫層級 Primary Key / Unique Constraint最可靠、效能最好、跨應用共享需資料庫支援 (Paradox/dBASE 支援有限)
TTable.BeforePost + FindKey (本文)無需資料庫結構變更、邏輯集中在應用層高併發下可能有競態條件 (需鎖表/交易)
OnValidate 檢查即時回饋 (離開欄位時)同樣有競態風險
ClientDataSet + OnReconcileError離線模式友善架構較複雜

進階:高併發環境下的補強


// 在資料庫支援交易時 (如 InterBase, Firebird, SQL Server)
procedure TForm1.Table1BeforePost(DataSet: TDataSet);
begin
  Database1.StartTransaction;
  try
    // ... FindKey 檢查 ...
    // ... 正常 Post ...
    Database1.Commit;
  except
    Database1.Rollback;
    raise;
  end;
end;

小結

BeforePost + FindKey + Abort 是 Delphi BDE/ADO 傳統架構下防止重複鍵值的經典寫法。理解 SetKey/GotoKey 索引尋找機制、Abort 取消寫入語意、獨立 TTable 避免游標衝突,即可靈活應用於各類唯一性驗證場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved