确实ADO有记录/密钥已删除错误?

问题描述:

我正在使用Delphi 7+ SQL服务器。确实ADO有记录/密钥已删除错误?

我正在将我的应用程序从BDE转换为ADO。 和他们正在处理的某些地方记录/密钥已删除错误和他们正在检查的错误代码是。

我们有记录/键删除ADO中的错误?任何人都可以解释我在什么情况下会引发这种错误?

+0

我正在使用DBGRID,TQUERY,TDATASOURCE,DBNAVIGATOR。是的,我想重现相同的BDE应用程序,所以我可以在ADO中复制相同的错误,我可以做错误处理。 – DelphiLearner

+0

@MartynA:我想在ADO中处理记录/键删除错误,我想知道错误代码。如果我能够在BDE中创建记录/键删除错误,我可以在ADO中处理微型示例,并且我可以执行错误处理。 – DelphiLearner

+0

@MartynA:我编辑了我的问题。你可以请现在检查吗? – DelphiLearner

以下内容可帮助您探索如何使用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