从表中删除记录(多对多关系)

时间:2012-09-22 08:03:52

标签: sql oracle

我有三张桌子:

PERSON
-ID_PERSON
-NAME
-SURNAME

PERSON_ADDRESS
-ID_PERSON
-ID_ADDRESS

ADDRESS
-ID_ADDRESS
-NR_LOCAL
-NR_HOME
-PLACE

我想用ADRESS表删除所有记录,其中id_person = 1

我的查询(在oracle中)

DELETE * FROM address INNER JOIN person_addres ON
address.id_address=person_addres.id_address 
WHERE person_addres.id_person=1 ;

5 个答案:

答案 0 :(得分:1)

在您的情况下,personaddress表具有多对多关系。这意味着一个人能够拥有多个地址,同时一个地址可能属于多个人。您想要删除特定人员的地址,并且您想要从address表中删除它。让我们考虑以下情况。 ID = 1的人根据person_address表具有ID = 2的地址,ID = 2的人具有相同的地址(ID = 2)。如果您删除了与人#1(ID = 1)相关的地址记录,会发生什么?第2个人将没有地址,或者您将获得integrity constraint violated(取决于您的on delete选项)。

要删除特定人员的地址,请将其他人的地址保持完整,最好从person_address表中删除address表中的记录。仅当没有分配了该地址的人员时,才从address表中删除记录。

要删除特定人员(在这种情况下ID = 1的人)的所有“地址”(来自person_address表的所有记录),您可以使用以下SQL。

delete 
  from (select q.id_person
          from address t
          join person_address q
            on (q.id_address = t.id_address)
        ) x
  where x.id_person = 1 

答案 1 :(得分:0)

  

“我想删除所有带有ADRESS表的记录,其中id_person = 1”

您与人物和地址之间存在多对多关系。这意味着您将删除由id_person != 1所在的人员使用的地址记录。那是你真正想做的吗?

假设是这种情况,您需要分三步完成:

  1. id_address person_address
  2. 中获取id_person=1的所有值
  3. 删除person_address
  4. 中的所有匹配记录
  5. 删除address
  6. 中的所有匹配记录

    在Oracle中,您可以使用批量操作和预定义的ODCINUMBERLIST集合在两个语句中执行此操作(我希望您的ID是数字)。

    declare
        addr_nt ODCINUMBERLIST;
    begin
        delete from person_address
        where id_person=1
        returning id_address bulk collect into addr_nt;
    
        forall i in addr_nt.first..addr_nt.last
            delete from address
            where addr_id = addr_nt(i);
     end;
    

    当然,如果你没有在表之间定义外键,你可以按照其他建议轻轻地从address表中删除。您的数据将是腐败和不可靠的,但这是不执行关系完整性的代价。

答案 2 :(得分:0)

表person_address 应该对表人员和地址具有外键约束。 要优雅地删除某人,请考虑使用此过程。

虽然我个人永远不会删除人员详细信息,而是在表格中列出具有该人员状态的列(例如,活动或非活动)。

create or replace procedure remove_person(p_id_person in person.id_person%type )
is
begin
    delete from person where id_person = p_id_person;
    delete from address where id_address in (select id_address from person_address where id_person = p_id_person);
    delete from person_address where id_person = p_id_person;

-- no exception handling, I want to know when this fails
end;

然后像这样使用:

begin
  remove_person(1);
end;

答案 3 :(得分:-1)

尝试进行子选择 - 抱歉我的Oracle生锈了:

DELETE * FROM address WHERE id_address IN (SELECT id_address FROM person_address WHERE id_person = 1)

答案 4 :(得分:-1)

首先从人员地址中选择地址ID,其中person_id = 1,然后从地址i中删除行,其中地址i等于先前查询的结果。这就是全部

DELETE * FROM ADDRESS WHERE ID_ADDRESS IN ( SELECT ID_ADDRESS FROM PERSON_ADDRESS WHERE ID_PERSON='1')