2017-01-13 20 views
0

我正在使用Delphi 7+ SQL服務器。確實ADO有記錄/密鑰已刪除錯誤?

我正在將我的應用程序從BDE轉換爲ADO。 和他們正在處理的某些地方記錄/密鑰已刪除錯誤和他們正在檢查的錯誤代碼是。

我們有記錄/鍵刪除ADO中的錯誤?任何人都可以解釋我在什麼情況下會引發這種錯誤?

+0

我正在使用DBGRID,TQUERY,TDATASOURCE,DBNAVIGATOR。是的,我想重現相同的BDE應用程序,所以我可以在ADO中複製相同的錯誤,我可以做錯誤處理。 – DelphiLearner

+0

@MartynA:我想在ADO中處理記錄/鍵刪除錯誤,我想知道錯誤代碼。如果我能夠在BDE中創建記錄/鍵刪除錯誤,我可以在ADO中處理微型示例,並且我可以執行錯誤處理。 – DelphiLearner

+0

@MartynA:我編輯了我的問題。你可以請現在檢查嗎? – DelphiLearner

回答

0

以下內容可幫助您探索如何使用TAdo *組件協調Sql Server表 中的更新衝突。通過準備,在您的服務器上創建一個像這樣的定義表格

CREATE TABLE [dbo].[ATable](
    [ID] [int] NOT NULL, 
    [name] [varchar](40) NOT NULL, 
PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

然後用幾行填充它。

然後,用TBGrid和TDNNavigator和下面的代碼創建一個最小的Ado Delphi項目。

更新如果你讀過我的回答原來的版本到你Q, 它在數據集上做批量更新方面的交談。然而,自發布以來,我發現 TAdoQuery.UpdateBatch工作方式似乎是異常的,所以我簡化了示例代碼 以避免使用批量更新。

現在,編譯並運行該項目,並在CMD窗口中打開它的第二個實例。 在第二個實例中更改一行中的[name]字段並將其保存,然後嘗試使 對IDE實例中同一行發生不同的更改。你應該得到一個錯誤 與單詞的效果

記錄不能找到更新。自上次閱讀 以來,某些值可能已更改。

你如何處理這種情況完全取決於你。例如,您可以保存行的 字段的當前用戶版本的本地副本,取消對該行的編輯,然後從服務器獲取新行版本,並詢問用戶 是否應將其更改應用於該行。

你應該看到的是,當出現錯誤時,NativeError代碼爲32。不幸的是,這也是NativeError返回時,應用程序的第二個實例 刪除記錄,而不是改變它(這 有意義的方式,因爲在任何一種情況下,服務器表中都不再存在該記錄的原始版本 。如果要使 能夠區分已更改的行和已刪除的行,可以運行查詢對錶 查看是否存在具有當前行ID的行。

代碼

type 
    TForm1 = class(TForm) 
    DataSource1: TDataSource; 
    DBGrid1: TDBGrid; 
    DBNavigator1: TDBNavigator; 
    ADOConnection1: TADOConnection; 
    ADOQuery1: TADOQuery; 
    Button1: TButton; 
    Memo1: TMemo; 
    procedure FormCreate(Sender: TObject); 
    private 
    procedure OnException(Sender: TObject; E: Exception); 
    public 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    Application.OnException := OnException; 
    AdoQuery1.LockType := ltOptimistic; 
    AdoQuery1.CursorType := ctKeySet; 
    AdoQuery1.SQL.Text := 'select * from atable'; 
    AdoQuery1.Open; 
    DBGrid1.Options := DBGrid1.Options + [dgEditing]; 
    DBGrid1.Columns[0].ReadOnly := True; 
end; 

procedure TForm1.OnException(Sender: TObject; E: Exception); 
var 
    AErrors : Errors; 
    AError : Error; 
    i : Integer; 
    S : String; 
begin 
    Caption := 'Exception'; 
    if E is EDatabaseError then begin 
    AErrors := AdoQuery1.Connection.Errors; 
    for i := 0 to AErrors.Count - 1 do begin 
     AError := AErrors.Item[i]; 
     S := Format('Number: %d, NativeError: %d, source: %s, description: %s', 
     [AError.Number, AError.NativeError, AError.Source, AError.Description]); 
     Memo1.Lines.Add(S); 
    end; 
    end; 
end; 

end. 
+0

@ kobik:原本我做過,是的,謝謝你指出。然而,正如我在我的更新中提到的,自發布我的答案以來,我已經注意到'TCustomAdoDataSet.UpdateBatch'中似乎是一個異常,所以我重新做了我的答案以避免批量更新。我稍後會研究一下,因爲我不確定這是否是一種真正的異常,或者只是我有一個「高級時刻」。 – MartynA

+0

@ kobik,謝謝,但那不是我遇到的異常情況。一旦我明白了我的想法,我可以嘗試解釋。 – MartynA