1

我有三张桌子:

PERSON
-ID_PERSON
-NAME
-SURNAME

PERSON_ADDRESS
-ID_PERSON
-ID_ADDRESS

ADDRESS
-ID_ADDRESS
-NR_LOCAL
-NR_HOME
-PLACE

我想删除 id_person=1 的 ADRESS 表中的所有记录

我的查询(在 oracle 中)

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

5 回答 5

1

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

要删除特定人的地址,保留其他人的地址不变,最好从person_address表中删除记录而不是address. address并且仅当没有分配该地址的人时才从表中删除记录。

person_address要删除特定人(本例中 ID = 1 的人)的所有“地址”(表中的所有记录),您可以使用以下 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 
于 2012-09-22T09:52:45.440 回答
0

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

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

假设是这种情况,您需要分三个步骤执行此操作:

  1. 获取其中id_address的所有值 person_addressid_person=1
  2. 删除所有匹配的记录person_address
  3. 删除所有匹配的记录address

在 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表中删除。您的数据将损坏且不可靠,但这是不执行关系完整性的代价。

于 2012-09-22T08:43:38.523 回答
0

表 person_address应该对表 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;
于 2012-09-22T09:47:43.827 回答
-1

尝试做一个子选择 - 抱歉我的 Oracle 生锈了:

DELETE * FROM address WHERE id_address IN (SELECT id_address FROM person_address WHERE id_person = 1)
于 2012-09-22T08:06:54.983 回答
-1

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

DELETE * FROM ADDRESS WHERE ID_ADDRESS IN ( SELECT ID_ADDRESS FROM PERSON_ADDRESS WHERE ID_PERSON='1')
于 2012-09-22T08:11:16.657 回答