Q:在多人使用的環境下如何確保主鍵值為唯一? 亦即如何產生唯一的鍵值? A:參考以下程式碼, 由 Bill Todd (TeamB) 提供 function dgGetUniqueNumber(LastNumberTbl: TTable): LongInt; {Gets the next value from a one field one record table which stores the last used value in its first field. The parameter LastNumberTbl is the table that contains the last used number.} const ntMaxTries = 100; var I, WaitCount, Tries: Integer; RecordLocked: Boolean; ErrorMsg: String; begin Result := 0; Tries := 0; with LastNumberTbl do begin {Make sure the table contains a record. If not, add one and set the first field to zero.} if RecordCount = 0 then begin Insert; Fields[0].AsInteger := 0; Post; end; file://if {Try to put the table that holds the last used number into edit mode. If calling Edit raises an exception wait a random period and try again.} Randomize; while Tries < ntMaxTries do try Inc(Tries); Edit; Break; except on E: EDBEngineError do {The call to Edit failed because the record could not be locked.} begin {See if the lock failed because the record is locked by another user.} RecordLocked := False; for I := 0 to Pred(E.ErrorCount) do if E.Errors[I].ErrorCode = 10241 then RecordLocked := True; if RecordLocked then begin {Wait for a random period and try again.} WaitCount := Random(20); for I := 1 to WaitCount do Application.ProcessMessages; Continue; end else begin {The record lock failed for some reason other than another user has the record locked. Display the BDE error stack and exit.} ErrorMsg := ''; for I := 0 to Pred(E.ErrorCount) do ErrorMsg := ErrorMsg + E.Errors[I].Message + ' (' + IntToStr(E.Errors[I].ErrorCode) + '). '; MessageDlg(ErrorMsg, mtError, [mbOK], 0); Exit; end; file://if end; end; {try} if State = dsEdit then begin Result := Fields[0].AsInteger + 1; Fields[0].AsInteger := Result; Post; end else {If the record could not be locked after the specified number of tries raise an exception.} raise Exception.Create('Cannot get next unique number. (dgGetUniqueNumber)'); end; end;