我用DBNavigator操作数据库,如果操作数据库时有些主键重复,主键为空的错误应该在DBNavigator的什么事件里写代码提示错误?

解决方案 »

  1.   

    恩,是不是在OnPostError事件里捕捉EDatabaseError的错误?EDatabaseError的错误类别有多少?
    有人能写一下吗?
      

  2.   

    (*
      This example represents a sampling of the way that you might
      approach trapping a number of database errors.
      A complete listing of the database errorcodes is found in the
      DBIErrs.Int file in the Delphi/Doc directory or in the IDAPI.h
      file in the Borland Database Engine.  Database errors are defined by category and code. Here's a sample:{ ERRCAT_INTEGRITY }  ERRCODE_KEYVIOL               = 1;  { Key violation }
      ERRCODE_MINVALERR             = 2;  { Min val check failed }
      ERRCODE_MAXVALERR             = 3;  { Max val check failed }
      ERRCODE_REQDERR               = 4;  { Field value required }
      ERRCODE_FORIEGNKEYERR         = 5;  { Master record missing }
      ERRCODE_DETAILRECORDSEXIST    = 6;  { Cannot MODIFY or DELETE this Master record }
      ERRCODE_MASTERTBLLEVEL        = 7;  { Master Table Level is incorrect }
      ERRCODE_LOOKUPTABLEERR        = 8;  { Field value out of lookup tbl range }
      ERRCODE_LOOKUPTBLOPENERR      = 9;  { Lookup Table Open failed }
      ERRCODE_DETAILTBLOPENERR      = 10; { 0x0a Detail Table Open failed }
      ERRCODE_MASTERTBLOPENERR      = 11; { 0x0b Master Table Open failed }
      ERRCODE_FIELDISBLANK          = 12; { 0x0c Field is blank }
      The constant for the base category is added to these constants to represent
      a unique DBI errorcode;  DBIERR_KEYVIOL  = (ERRBASE_INTEGRITY + ERRCODE_KEYVIOL);
      DBIERR_REQDERR = (ERRBASE_INTEGRITY + ERRCODE_REQDERR);
      DBIERR_DETAILRECORDSEXIST = (ERRBASE_INTEGRITY + ERRCODE_DETAILRECORDSEXIST);
      DBIERR_FORIEGNKEYERR = (ERRBASE_INTEGRITY + ERRCODE_FORIEGNKEYERR);  The ERRBASE_INTEGRITY value is $2600 (Hex 2600) or 9728 decimal.
      Thus, for example, the errorcode for keyviol is 9729
                                       for master with details is 9734.  *)unit DM1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      DBTables, DB;type
      TDM = class(TDataModule)
        Customer: TTable;
        CustomerCustNo: TFloatField;
        CustomerCompany: TStringField;
        CustomerSource: TDataSource;
        Orders: TTable;
        OrdersSource: TDataSource;
        Items: TTable;
        ItemsOrderNo: TFloatField;
        ItemsItemNo: TFloatField;
        ItemsPartNo: TFloatField;
        ItemsQty: TIntegerField;
        ItemsDiscount: TFloatField;
        ItemsSource: TDataSource;
        OrdersOrderNo: TFloatField;
        OrdersCustNo: TFloatField;
        OrdersSaleDate: TDateTimeField;
        OrdersShipDate: TDateTimeField;
        OrdersEmpNo: TIntegerField;
        procedure CustomerPostError(DataSet: TDataSet; E: EDatabaseError;
          var Action: TDataAction);
        procedure CustomerDeleteError(DataSet: TDataSet; E: EDatabaseError;
          var Action: TDataAction);
        procedure ItemsPostError(DataSet: TDataSet; E: EDatabaseError;
          var Action: TDataAction);
        procedure OrdersPostError(DataSet: TDataSet; E: EDatabaseError;
          var Action: TDataAction);
        procedure OrdersDeleteError(DataSet: TDataSet; E: EDatabaseError;
          var Action: TDataAction);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      DM: TDM;const
      {Declare constants we're interested in}
      eKeyViol = 9729;
      eRequiredFieldMissing = 9732;
      eForeignKey = 9733;
      eDetailsExist = 9734;
    implementation{$R *.dfm}procedure TDM.CustomerPostError(DataSet: TDataSet;
      E: EDatabaseError; var Action: TDataAction);
    begin
      if (E is EDBEngineError) then
        if (E as EDBEngineError).Errors[0].Errorcode = eKeyViol then
        begin
          MessageDlg('Unable to post: Duplicate Customer ID.', mtWarning, [mbOK], 0);
          Abort;
        end;
     end;procedure TDM.CustomerDeleteError(DataSet: TDataSet;
      E: EDatabaseError; var Action: TDataAction);
    begin
      if (E is EDBEngineError) then
        if (E as EDBEngineError).Errors[0].Errorcode = eDetailsExist then
        {the customer record has dependent details in the Orders table.}
        begin
          MessageDlg('To delete this record, first delete related orders and items.',
            mtWarning, [mbOK], 0);
          Abort;
        end;
    end;procedure TDM.ItemsPostError(DataSet: TDataSet; E: EDatabaseError;
      var Action: TDataAction);
    begin
      {This error will occur when a part number is specified that
       is not in the parts table.}
      if (E as EDBEngineError).Errors[0].Errorcode = eForeignKey then
      begin
        MessageDlg('Part number is invalid', mtWarning,[mbOK],0);
        Abort;
      end;
    end;procedure TDM.OrdersPostError(DataSet: TDataSet; E: EDatabaseError;
      var Action: TDataAction);
    var
      iDBIError: Integer;
    begin
      if (E is EDBEngineError) then
      begin
        iDBIError := (E as EDBEngineError).Errors[0].Errorcode;
        case iDBIError of
          eRequiredFieldMissing:
            {The EmpNo field is defined as being required.}
            begin
              MessageDlg('Please provide an Employee ID', mtWarning, [mbOK], 0);
              Abort;
            end;
          eKeyViol:
            {The primary key is OrderNo}
            begin
              MessageDlg('Unable to post. Duplicate Order Number', mtWarning,
                [mbOK], 0);
              Abort;
            end;
        end;
      end;
    end;procedure TDM.OrdersDeleteError(DataSet: TDataSet; E: EDatabaseError;
      var Action: TDataAction);
    begin
      if E is EDBEngineError then
        if (E as EDBEngineError).Errors[0].Errorcode = eDetailsExist then
        begin
          if MessageDlg('Delete this order and related items?', mtConfirmation,
            [mbYes, mbNo], 0) = mrYes then
          begin
            {Delete related records in linked 'items' table}
            while Items.RecordCount > 0 do
              Items.delete;
            {Finally,delete this record}
            Action := daRetry;
          end else Abort;
        end;
    end;end.=========================================================================unit Main;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      Grids, DBGrids, ExtCtrls, DBCtrls, DB, DBTables, StdCtrls, Menus;type
      TFmMain = class(TForm)
        DBNavigator1: TDBNavigator;
        GridCustomers: TDBGrid;
        GridOrders: TDBGrid;
        GridItems: TDBGrid;
        Label1: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        MainMenu1: TMainMenu;
        About1: TMenuItem;
        procedure GridOrdersEnter(Sender: TObject);
        procedure GridCustomersEnter(Sender: TObject);
        procedure GridItemsEnter(Sender: TObject);
        procedure GridCustomersExit(Sender: TObject);
        procedure About1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      FmMain: TFmMain;implementationuses DM1, About;  {$R *.dfm}procedure TFmMain.GridOrdersEnter(Sender: TObject);
    begin
      DBNavigator1.DataSource := Dm.OrdersSource;
    end;procedure TFmMain.GridCustomersEnter(Sender: TObject);
    begin
      DBNavigator1.DataSource := Dm.CustomerSource;
    end;procedure TFmMain.GridItemsEnter(Sender: TObject);
    begin
      DBNavigator1.DataSource := Dm.ItemsSource;
    end;procedure TFmMain.GridCustomersExit(Sender: TObject);
    begin
      if Dm.Customer.State in [dsEdit,dsInsert] then
        Dm.Customer.Post; {required if user clicks onto details
                           after changing key so that cascaded
                           update displays properly}
    end;procedure TFmMain.About1Click(Sender: TObject);
    var
      fmAboutBox : TFmAboutBox;
    begin
      FmAboutBox := TFmAboutBox.Create(self);
      try
        FmAboutBox.showModal;
      finally
        FmAboutBox.free;
      end;
    end;end.
      

  3.   

    本来这些错误的数据就不应该被输入系统中!我觉得还是从第一关做起吧!先把数据Post时的肯问题解决了,这个就不是问题了!要不后患无穷!