tags:

views:

30

answers:

1

I've got some linked tables in a Postgres database, as follows:

    Table "public.key"
 Column | Type | Modifiers 
--------+------+-----------
 id     | text | not null
 name   | text | 
Referenced by:
    TABLE "enumeration_value" CONSTRAINT "enumeration_value_key_id_fkey" FOREIGN KEY (key_id) REFERENCES key(id)

Table "public.enumeration_value"
 Column | Type | Modifiers 
--------+------+-----------
 id     | text | not null
 key_id | text | 
Foreign-key constraints:
    "enumeration_value_key_id_fkey" FOREIGN KEY (key_id) REFERENCES key(id)
Referenced by:
    TABLE "classification_item" CONSTRAINT "classification_item_value_id_fkey" FOREIGN KEY (value_id) REFERENCES enumeration_value(id)

Table "public.classification_item"
     Column     | Type | Modifiers 
----------------+------+-----------
 id             | text | not null
 transaction_id | text | 
 value_id       | text | 
Foreign-key constraints:
    "classification_item_transaction_id_fkey" FOREIGN KEY (transaction_id) REFERENCES transaction(id)
    "classification_item_value_id_fkey" FOREIGN KEY (value_id) REFERENCES enumeration_value(id)

I want to

  • delete all classification_items associated with a certain transaction
  • delete all enumeration_values associated with those classification_items
  • and finally, delete all key items associated with those enumeration_values.

The difficulty is that the key items are NOT unique to enumeration_values associated (via classification_item) with a certain transaction. They get created independently, and can exist across multiple of these transactions.

So I know how to do the second two of these steps, but not the first one:

delete from key where id in (select key_id from enumeration_value where id in (select value_id from "classification_item" where id = (select id from "transaction" where slice_id = (select id from slice where name = 'barnet')))); 
# In statement above: help! How do I make sure these keys are ONLY used with these values?
delete from enumeration_value where id in (select value_id from "classification_item" where id = (select id from "transaction" where slice_id = (select id from slice where name = 'barnet')));
delete from classification_item where transaction_id in (select id from "transaction" where slice_id = (select id from slice where name = 'barnet'));

If only postgres had a CASCADE DELETE statement....

+1  A: 

If only postgres had a CASCADE DELETE statement....

PostgreSQL has this option for a long time, as of version 8.0 (5 years ago). Just use them.

Frank Heikens
http://www.postgresql.org/docs/7.4/interactive/ddl-constraints.html has it too (released 2003). I would be surprised if it was not in earlier versions, too.
Unreason
Didn't take a look in the 7.4-documentation ;)
Frank Heikens
Alas, that doesn't help, because it's not my database - I've inherited it, and I don't have the option to rebuild it from scratch.
AP257
Then why do you complain about PostgreSQL when the real problem is your datamodel and you don't want to fix it? It's not rocket science and you only have to fix the parts that give you problems right now.
Frank Heikens
Fair point, but I'm not sure what you mean by 'fix'. If you mean delete all the data and recreate the database from scratch, unfortunately that's not an option, for various reasons.
AP257
You have to change your foreign keys into cascading foreign keys. Just drop the current foreign key and add a cascading foreign key. That's it! The manual will tell you how to do it, just check the ALTER TABLE statements.
Frank Heikens
Oh I see :) thanks!
AP257