ADO有记录/密钥删除错误吗?

时间:2017-01-13 13:53:02

标签: delphi delphi-7

我正在使用Delphi 7+ SQL服务器。

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

我们在ADO中有记录/密钥删除错误吗?并且任何人都可以解释我会在什么情况下引发错误?

1 个答案:

答案 0 :(得分:0)

以下内容可帮助您探索如何协调Sql Server表中的更新冲突 使用TAdo *组件。通过准备,在服务器上创建一个具有此类定义的表

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.