имеет ли ADO запись/ключ удалена ошибка?

я работаю на Delphi 7 + SQL server.

я конвертирую мое приложение из BDE в ADO.
и в некоторых местах они обрабатывают ошибку записи / ключа удаленную и код ошибки они проверяют для 8708 .

у нас есть запись/ключ удален ошибка в ADO? и может ли кто-нибудь объяснить мне, в каком случае это вызовет эту ошибку?

1 ответ

  1. Ниже приведены инструкции по разрешению конфликтов обновлений в таблицах 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]
    

    а затем заполнить его несколькими рядами.

    Затем создайте минимальный проект Ado Delphi с TBGrid и TDNNavigator и кодом ниже.

    Обновление, если вы прочитали исходную версию моего ответа на ваш вопрос,
    речь шла о пакетных обновлениях набора данных. Тем не менее, с момента публикации я обнаружил, что кажется аномалией в том, как
    TAdoQuery.UpdateBatchработает, поэтому я упростил пример кода
    чтобы избежать использования пакетных обновлений.

    Теперь скомпилируйте и запустите проект и откройте его второй экземпляр в окне CMD.
    Измените поле [name] в строке во 2-м экземпляре и сохраните его, затем попробуйте сделать
    другое изменение той же строки в экземпляре IDE. Вы должны получить ошибку
    со словами в эффект

    Запись не может быть найдена для обновления. Некоторые значения могут изменяться с момента was
    последнее чтение.

    Как вы справляетесь с этим условием полностью зависит от вас. Например, можно сохранить локальную копию версии строки текущего пользователя
    поля, отменить редактирование строки, а затем получить новую версию строки с сервера и спросить пользователя
    следует ли применять к нему его изменения.

    Вы должны видеть, что при возникновении ошибки код NativeError равен 32. К сожалению, это также NativeError вернулся, когда второй
    экземпляр приложения удаляет запись, а не изменяет ее (которая
    имеет смысл в некотором смысле, потому что в любом случае, оригинальная версия
    записи больше не существует в таблице сервера. Если вы хотите быть
    способный различить между строками которые были изменены и одними которые
    были удалены, вы можете, например, запустить запрос к таблице, чтобы
    посмотрите, существует ли строка с текущим идентификатором строки.

    Код

    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.