Solved

Working with CacheUpdate !!

Posted on 1998-05-31
1
469 Views
Last Modified: 2010-04-03
Hi,
I am working in delphi 3.0 using  'Paradox' ..I have two tables which are order_master and order_detail and i have a form in which both have master detail relationship i mean its a master detail form using the above tables..and cahcheupdate property is true in both tables.

So in case of keyviolation in detail table I want to trap this keyviolation on order_detail  but you know when cahcheupdate is true then it wont work coz changes are going in a temporary area...not physically...so is there any method of preventing duplicate values in detail when cacheupdate is true...

your help in this matter will higly appreciated...

thanks,
Zahid

0
Comment
Question by:zahzia
1 Comment
 
LVL 1

Accepted Solution

by:
Edo082297 earned 20 total points
ID: 1349438
Hi Zahid,
   There is no magic solution to predicting or preventing key violations. However, you can deal with them in a more sophisticated manner than the default behavior provided by Delphi.
  You need to use transactions. A transaction applies updates in an all or nothing fashion. There are two solutions to providing transaction control with cached updates. One is to provide a transaction wrapper around your call to a DataSet's ApplyUpdates method. The second is to use the ApplyUpdates method of the DataSet's Database property (what we'll do). The database property is just a pointer to a Database object you put on your form (which you could do) or the database object that you reference (Delphi will create one for you automatically). Note that since you are using Paradox local tables, you must set the transisolation property of the database object to tiDirtyRead in your code. (This just means that the records will be treated as if the records are being automatically committed, even though a transaction might get rolled back). Note that you do not need to put a database object on your form for all this to work! If you would prefer to do so, drop one on the form and set your datasets to point to it through their datasource property.
   The database object provides transaction processing. It is the way that we will implement a solution. If you look at the following code, you will notice commit being called prior to commitupdate. The purpose of committing a transaction prior to committing the updates is that you do not want to commit the updates (which flushes the cache) if the committing of the transaction fails (due to a key violation, or a data constraint, etc...).

Table1.Database.StartTransaction;
try
  Table1.ApplyUpdates;
  Table1.Database.Commit;
  Table1.CommitUpdates;
except
  Table1.Database.Rollback;
  raise;
end;

   You cannot prevent the user from trying to insert a record that will cause a key violation. However, by providing a handler for the OnUpdateError, you can do some other processing, skip over the offender, or allow the user to insert another value. An exception type is part of this events signature so that you know what went wrong.
  In this example, we catch key violations and allow the user to insert another value before attempting to update the record again:

procedure TForm1.Table1UpdateError(DataSet: TDataSet; E: EDatabaseError; UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
Var
  BdeError: PChar;  NewVal: String;
begin
  GetMem(BdeError, 1024);
  try
    BDE.DbiGetErrorString(DBIERR_KEYVIOL,BdeError);
    //Test if a key violation message is in the exception.
    //If a key violation occurred, permit the user to enter a new key
    if E.message = copy(StrPas(BdeError),1,Length(E.message)) then  
    begin
      NewVal := DataSet.Fields[0].NewValue;
      if InputQuery('Key violation','Enter new key',NewVal) then
      begin
        DataSet.Edit;
        DataSet.Fields[0].Value := NewVal;
        DataSet.Fields[0].NewValue := NewVal;
        UpdateAction := uaRetry;
      end
    else
      //Use uaAbort since the user has clicked Cancel.
      //No error message is necessary.
      UpdateAction := uaAbort;
  end
else
  ;//The default UpdateAction is uaFail.
   //Permit the update to fail.
finally
  FreeMem(BdeError);
end;

end;

  This event handler includes a case statement to test the value of UpdateKind. If the current record is being inserted, a new record is added to the table, the fields of the Query are assigned to the fields of the table, and then the record is posted. If the record has been modified, the existing record is located in the table, and then its fields are updated. If the record has been deleted, again the corresponding record is located in the table and deleted. If the actions of this event handler do not raise an exception, the final statement sets the UpdateAction parameter to uaApplied. If an exception is raised, the UpdateAction's default value of uaFail remains unchanged, causing the update to fail.
  It is not the greatest idea to let the user make changes while transactions are occurring, but it may suit your needs. Make sure to thoroughly test a handler such as this.
  There is an awful lot to cached updates; read up on this event (OnUpdateError) and the OnUpdateRecord event which allows a great deal of customization to the way transactions are implemented.

HTH

Edo

0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now