Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 14 total
Thread Foreign Key with DELETE CASCADE
Sun, Mar 21 2010 4:25 PMPermanent Link

MatthiasThaler

Hello

I want to add a foreign key with automatic delete, but didn't succed so far.
e.g. delete a customer, deletes all orders.

Thanks
Sun, Mar 21 2010 8:24 PMPermanent Link

Jan Ferguson

Data Software Solutions, Inc.

Team Elevate Team Elevate

Thaler,

You cannot do that with ElevateDB, at this point in time. ElevateDB
currently only allows "Restrict"  or "No Action". You would have to do
that in your BeforeDelete code.

var CustomerNumber: String;
begin
if tblCustomerOrders.RecordCount > 0 then
  begin
    CustomerNumber := IntToStr(tblCustomersCustomerNumber.Value);
    tblCustomerOrders.IndexName := 'CustomerNumber';
    tblCustomerOrders.First;
    tblCustomerOrders.SetRange ([CustomerNumber], [CustomerNumber]);
    tblCustomerOrders.ApplyRange;
    while not tblCustomerOrders.EOF do
       begin
         tblCustomerOrders.Delete;
       end;
    tblCustomerOrders.CancelRange;
  end else
    begin
       ShowMessage('There are no orders for this customer.');
    end;
end;

--
Jan Ferguson


Thaler Matthias wrote:

> I want to add a foreign key with automatic delete, but didn't succed
> so far.  e.g. delete a customer, deletes all orders.
Mon, Mar 22 2010 2:38 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Thaler

Or in an AfterDelete trigger eg


TRIGGER "CustomerAfterDelete"
BEGIN
EXECUTE IMMEDIATE 'DELETE FROM Orders WHERE fkCustomer = '+CAST(OLDROW._CustomerID AS VARCHAR);
END

Roy Lambert
Mon, Mar 22 2010 11:40 AMPermanent Link

MatthiasThaler

Thanks for your suggestions.

To Roy: I'm not sure wheter to take before-delete of after-delete ?
Should I add a transaction ?

Greets Matthias
Mon, Mar 22 2010 12:28 PMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

MatthiasThaler

>To Roy: I'm not sure wheter to take before-delete of after-delete ?
>Should I add a transaction ?

Without knowing details of your app I can only say how I'd do it.

If you select BeforeDelete then there is a chance that the customer isn't deleted so you'd need some sort of exception handling. AfterDelete the customer has gone so "all" you need to do is clean up the orders. This is where it could get tricky. Firstly I don't know whether you just have an order or an order header and associated order lines. The principle is pretty much the same but if the latter will need a few more lines of code.

It might be possible for someone to be editing an order at the time you're deleting a customer. If you don't have a lock on the customer the delete of the customer will work but when you try to delete the order there may be an edit lock in place which could prevent the delete succeeding. To cope with that you need something like

DECLARE LoopControl BOOLEAN;

SET LoopControl = TRUE;

WHILE LoopControl DO
BEGIN
EXECUTE IMMEDIATE 'DELETE FROM Orders WHERE fkCustomer = '+CAST(OLDROW._CustomerID AS VARCHAR);
SET LoopControl = FALSE;
EXCEPTION
END;
END WHILE;

Totally untested of course so use at your own risk Smiley

If you have order header and order lines then if the customer code is stored at order line you can just add one line to zap those, if not I'd probably use a cursor to get the order headers and a loop to zap associated lines. Again I probably wouldn't bother with a transaction, just keep trying until I get them.

Something you'll need to give thought to is wether or not there's a chance of a deadlock developing.

Roy Lambert [Team Elevate]
Mon, Mar 22 2010 12:31 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Matthias,

<< To Roy: I'm not sure wheter to take before-delete of after-delete ?
Should I add a transaction ? >>

Start a transaction on just the two tables in the BEFORE DELETE trigger:

CREATE TRIGGER BeforeDeleteTrigger BEFORE DELETE ON Master
BEGIN
   START TRANSACTION ON TABLES Master, Detail;
END

commit the transaction after the delete:

CREATE TRIGGER AfterDeleteTrigger AFTER DELETE ON Master
BEGIN
   COMMIT;
END

be sure to roll it back if there's an error using an ERROR trigger:

CREATE TRIGGER ErrorDeleteTrigger ERROR DELETE ON Master
BEGIN
   ROLLBACK;
END

--
Tim Young
Elevate Software
www.elevatesoft.com

Mon, Mar 22 2010 12:39 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Matthias,

Duh, I forgot to add a mention of the actual deletes:

delete the rows and commit the transaction after the delete:

CREATE TRIGGER AfterDeleteTrigger AFTER DELETE ON Master
BEGIN
   EXECUTE IMMEDIATE 'DELETE FROM Detail WHERE MasterID='+OLDROW.ID;
   COMMIT;
END

--
Tim Young
Elevate Software
www.elevatesoft.com

Mon, Mar 22 2010 12:47 PMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Tim


That's neat. I never knew transactions could span triggers like that.

Roy Lambert
Mon, Mar 22 2010 2:07 PMPermanent Link

MatthiasThaler

Thanks, I will try that.
Tue, Mar 23 2010 1:14 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Roy,

<< That's neat. I never knew transactions could span triggers like that. >>

Sure, the triggers act just like engine-level
BeforePost/AfterPost/OnPostError event handlers.

--
Tim Young
Elevate Software
www.elevatesoft.com

Page 1 of 2Next Page »
Jump to Page:  1 2
Image