Postgres:复杂的CASCADE问题 - 确保只删除唯一的外键引用?

时间:2010-09-20 11:48:57

标签: postgresql

我在Postgres数据库中有一些链接表,如下所示:

    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)

我想

  • 删除与某个classification_items
  • 相关联的所有transaction
  • 删除与enumeration_values
  • 相关联的所有classification_items
  • 最后,删除与key相关联的所有enumeration_values项。

难点在于,key项并非与enumeration_values相关联(通过classification_item)与某个transaction无关。它们是独立创建的,并且可以存在于这些事务的多个中。

所以我知道如何做第二个步骤,但不是第一步:

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'));

如果只有postgres有一个CASCADE DELETE语句......

1 个答案:

答案 0 :(得分:1)

  

如果只有postgres有一个CASCADE DELETE   声明....

从版本8.0(5年前)开始,PostgreSQL很长一段时间都有这个选项。 Just use them.