views:

1184

answers:

1

Is there a special syntax to execute a cascade delete on DB2 or is it only possible to create "cascadable" tables by defining them with the "ON DELETE CASCADE" option?

What I am trying to achieve is delete other table rows based on a same foreign key when I delete that key, but this is done on an already existing and data-filled database.

+1  A: 

As you stated, you either have to create FKs with an ON DELETE CASCADE clause or to pre-delete the other rows with a subselect-delete.

So, if you don't have an ON DELETE CASCADE clause you have to do

DELETE FROM ORDERS_ITEMS WHERE ORDER_ID in (
    SELECT ORDER_ID FROM ORDERS WHERE STATUS = 'Canceled'
);

DELETE FROM ORDERS_ADDRESS WHERE ORDER_ID in (
    SELECT ORDER_ID FROM ORDERS WHERE STATUS = 'Canceled'
);

DELETE FROM ORDERS WHERE STATUS = 'Canceled';

It is simple, but is somewhat redundant so you may use the WITH statement.

If the request to select the required rows is quite big, and if you don't have at least a RR isolation level, you may have to use a TEMPORARY table :

DECLARE GLOBAL TEMPORARY TABLE TMP_IDS_TO_DELETE (ID BIGINT) NOT LOGGED;

INSERT INTO SESSION.TMP_IDS_TO_DELETE (ID)
    SELECT ORDER_ID FROM ORDERS WHERE STATUS = 'Canceled';

DELETE FROM ORDERS_ITEMS WHERE ORDER_ID in (
   SELECT ID FROM SESSION.TMP_IDS_TO_DELETE
);


DELETE FROM ORDERS_ADDRESS WHERE ORDER_ID in (
    SELECT ID FROM SESSION.TMP_IDS_TO_DELETE
);

DELETE FROM ORDERS WHERE ORDER_ID in (
    SELECT ID FROM SESSION.TMP_IDS_TO_DELETE
);

This way you are sure that you will delete the same rows in each table, and a FK error will still fire up if you miss something. Per default, the temporary table will empty itself on commit.

Steve Schnepp