home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1996 August / VPR9608A.BIN / del20try / install / data.z / DM1.PAS < prev    next >
Pascal/Delphi Source File  |  1996-05-08  |  6KB  |  205 lines

  1. (*
  2.   This example represents a sampling of the way that you might
  3.   approach trapping a number of database errors.
  4.  
  5.  
  6.   A complete listing of the database errorcodes is found in the
  7.   DBIErrs.Int file in the Delphi/Doc directory or in the IDAPI.h
  8.   file in the Borland Database Engine.
  9.  
  10.   Database errors are defined by category and code. Here's a sample:
  11.  
  12. { ERRCAT_INTEGRITY }
  13.  
  14.   ERRCODE_KEYVIOL               = 1;  { Key violation }
  15.   ERRCODE_MINVALERR             = 2;  { Min val check failed }
  16.   ERRCODE_MAXVALERR             = 3;  { Max val check failed }
  17.   ERRCODE_REQDERR               = 4;  { Field value required }
  18.   ERRCODE_FORIEGNKEYERR         = 5;  { Master record missing }
  19.   ERRCODE_DETAILRECORDSEXIST    = 6;  { Cannot MODIFY or DELETE this Master record }
  20.   ERRCODE_MASTERTBLLEVEL        = 7;  { Master Table Level is incorrect }
  21.   ERRCODE_LOOKUPTABLEERR        = 8;  { Field value out of lookup tbl range }
  22.   ERRCODE_LOOKUPTBLOPENERR      = 9;  { Lookup Table Open failed }
  23.   ERRCODE_DETAILTBLOPENERR      = 10; { 0x0a Detail Table Open failed }
  24.   ERRCODE_MASTERTBLOPENERR      = 11; { 0x0b Master Table Open failed }
  25.   ERRCODE_FIELDISBLANK          = 12; { 0x0c Field is blank }
  26.  
  27.  
  28.   The constant for the base category is added to these constants to represent
  29.   a unique DBI errorcode;
  30.  
  31.   DBIERR_KEYVIOL  = (ERRBASE_INTEGRITY + ERRCODE_KEYVIOL);
  32.   DBIERR_REQDERR = (ERRBASE_INTEGRITY + ERRCODE_REQDERR);
  33.   DBIERR_DETAILRECORDSEXIST = (ERRBASE_INTEGRITY + ERRCODE_DETAILRECORDSEXIST);
  34.   DBIERR_FORIEGNKEYERR = (ERRBASE_INTEGRITY + ERRCODE_FORIEGNKEYERR);
  35.  
  36.   The ERRBASE_INTEGRITY value is $2600 (Hex 2600) or 9728 decimal.
  37.   Thus, for example, the errorcode for keyviol is 9729
  38.                                    for master with details is 9734.
  39.  
  40.   *)
  41.  
  42. unit DM1;
  43.  
  44. interface
  45.  
  46. uses
  47.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  48.   DBTables, DB;
  49.  
  50. type
  51.   TDM = class(TDataModule)
  52.     Customer: TTable;
  53.     CustomerCustNo: TFloatField;
  54.     CustomerCompany: TStringField;
  55.     CustomerSource: TDataSource;
  56.     Orders: TTable;
  57.     OrdersSource: TDataSource;
  58.     Items: TTable;
  59.     ItemsOrderNo: TFloatField;
  60.     ItemsItemNo: TFloatField;
  61.     ItemsPartNo: TFloatField;
  62.     ItemsQty: TIntegerField;
  63.     ItemsDiscount: TFloatField;
  64.     ItemsSource: TDataSource;
  65.     OrdersOrderNo: TFloatField;
  66.     OrdersCustNo: TFloatField;
  67.     OrdersSaleDate: TDateTimeField;
  68.     OrdersShipDate: TDateTimeField;
  69.     OrdersEmpNo: TIntegerField;
  70.     procedure CustomerPostError(DataSet: TDataSet; E: EDatabaseError;
  71.       var Action: TDataAction);
  72.     procedure CustomerDeleteError(DataSet: TDataSet; E: EDatabaseError;
  73.       var Action: TDataAction);
  74.     procedure CustomerAfterPost(DataSet: TDataSet);
  75.     procedure CustomerCustNoChange(Sender: TField);
  76.     procedure ItemsPostError(DataSet: TDataSet; E: EDatabaseError;
  77.       var Action: TDataAction);
  78.     procedure OrdersPostError(DataSet: TDataSet; E: EDatabaseError;
  79.       var Action: TDataAction);
  80.     procedure OrdersDeleteError(DataSet: TDataSet; E: EDatabaseError;
  81.       var Action: TDataAction);
  82.   private
  83.     { Private declarations }
  84.   public
  85.     { Public declarations }
  86.   end;
  87.  
  88. var
  89.   DM: TDM;
  90.  
  91. const
  92.   {Declare constants we're interested in}
  93.   eKeyViol = 9729;
  94.   eRequiredFieldMissing = 9732;
  95.   eForeignKey = 9733;
  96.   eDetailsExist = 9734;
  97.  
  98.  
  99. implementation
  100.  
  101. {$R *.DFM}
  102.  
  103. procedure TDM.CustomerPostError(DataSet: TDataSet;
  104.   E: EDatabaseError; var Action: TDataAction);
  105. begin
  106.   if (E is EDBEngineError) then
  107.     if (E as EDBEngineError).Errors[0].Errorcode = eKeyViol then
  108.     begin
  109.       MessageDlg('Unable to post: Duplicate Customer ID.', mtWarning, [mbOK], 0);
  110.       Abort;
  111.     end;
  112.  end;
  113.  
  114. procedure TDM.CustomerDeleteError(DataSet: TDataSet;
  115.   E: EDatabaseError; var Action: TDataAction);
  116. begin
  117.   if (E is EDBEngineError) then
  118.     if (E as EDBEngineError).Errors[0].Errorcode = eDetailsExist then
  119.     {the customer record has dependent details in the Orders table.}
  120.     begin
  121.       MessageDlg('To delete this record, first delete related orders and items.',
  122.         mtWarning, [mbOK], 0);
  123.       Abort;
  124.     end;
  125. end;
  126.  
  127. procedure TDM.CustomerCustNoChange(Sender: TField);
  128. begin
  129.   {Field Level Event; This code is a 'cosmetic'
  130.    necessity when you change the key of the
  131.    CustNo in Customer to prevent unexpected changes
  132.    in the display of the related 'Orders' and
  133.    'Items' grids. These controls are re-enabled in the
  134.    CustomerAfterPost method.}
  135.   Orders.DisableControls;
  136.   Items.DisableControls;
  137. end;
  138.  
  139. procedure TDM.CustomerAfterPost(DataSet: TDataSet);
  140. begin
  141.   {See note in CustomerCustNoChange}
  142.   Dm.Orders.Refresh;
  143.   Dm.Items.Refresh;
  144.   Dm.Orders.EnableControls;
  145.   Dm.Items.EnableControls;
  146. end;
  147.  
  148. procedure TDM.ItemsPostError(DataSet: TDataSet; E: EDatabaseError;
  149.   var Action: TDataAction);
  150. begin
  151.   {This error will occur when a part number is specified that
  152.    is not in the parts table.}
  153.   if (E as EDBEngineError).Errors[0].Errorcode = eForeignKey then
  154.   begin
  155.     MessageDlg('Part number is invalid', mtWarning,[mbOK],0);
  156.     Abort;
  157.   end;
  158. end;
  159.  
  160. procedure TDM.OrdersPostError(DataSet: TDataSet; E: EDatabaseError;
  161.   var Action: TDataAction);
  162. var
  163.   iDBIError: Integer;
  164. begin
  165.   if (E is EDBEngineError) then
  166.   begin
  167.     iDBIError := (E as EDBEngineError).Errors[0].Errorcode;
  168.     case iDBIError of
  169.       eRequiredFieldMissing:
  170.         {The EmpNo field is defined as being required.}
  171.         begin
  172.           MessageDlg('Please provide an Employee ID', mtWarning, [mbOK], 0);
  173.           Abort;
  174.         end;
  175.       eKeyViol:
  176.         {The primary key is OrderNo}
  177.         begin
  178.           MessageDlg('Unable to post. Duplicate Order Number', mtWarning,
  179.             [mbOK], 0);
  180.           Abort;
  181.         end;
  182.     end;
  183.   end;
  184. end;
  185.  
  186. procedure TDM.OrdersDeleteError(DataSet: TDataSet; E: EDatabaseError;
  187.   var Action: TDataAction);
  188. begin
  189.   if E is EDBEngineError then
  190.     if (E as EDBEngineError).Errors[0].Errorcode = eDetailsExist then
  191.     begin
  192.       if MessageDlg('Delete this order and related items?', mtConfirmation,
  193.         [mbYes, mbNo], 0) = mrYes then
  194.       begin
  195.         {Delete related records in linked 'items' table}
  196.         while Items.RecordCount > 0 do
  197.           Items.delete;
  198.         {Finally,delete this record}
  199.         Action := daRetry;
  200.       end else Abort;
  201.     end;
  202. end;
  203.  
  204. end.
  205.