2012-09-22 250 views
1

我有三个表:删除记录

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 ; 

回答

-1

尝试做一个子选择 - 对不起我的Oracle是生锈:

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

我认为你必须删除'*' –

+0

我在想,太... – endyourif

+0

谢谢,我解决这个问题的方法(documenaction),谢谢。 – dexter90

-1

首先从person_id = 1的人员地址中选择地址标识,然后从地址i等于先前查询结果的地址中删除该行。这是所有

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

删除从(选择*从地址aa JOIN person_address oa ON aa.id_adres = oa.id_adres WHERE oa.id_person = 1) 删除记录与表person_address :( – dexter90

0

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

你有Person和地址之间的许多一对多的关系。这意味着您将删除id_person != 1的人员使用的地址记录。这就是你真正想做的事情吗?

。假定是这样的话,你需要做的这三个步骤:

  1. 得到person_addressid_address所有的值,其中id_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表中删除。您的数据将是腐败和不可靠的,但这是不执行关系完整性的代价。

+0

谢谢我明白,但我写的SQL不是PL/SQL和我将这个命令复制到Acces MS因为我正在编写应用程序databse。我很有趣简单的解决方法:)帮助:) – dexter90

+1

您应该在您的问题中指定* all *您的要求,而不是稍后在评论中添加它们。 – APC

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; 
+1

我个人认为你错了。逻辑删除引入了错误的可能性,使查询和关系完整性复杂化,甚至可能导致性能问题。正确的做法是从物理上删除PERSON,对任何记录进行ADDRESS,并使用审计或历史记录表来记录详细信息。 – APC

+0

此外,没有声明要求删除PERSON记录。如果每个PERSON_ID有多个ADDRESS,并且假定该模型实现M:N关系是一种极有可能的情况,那么您的代码将失败。 – APC

+0

好点。我调整了我的程序以考虑M:N关系。那里太快了。 ;) 逻辑删除对我来说很好,但审计或历史记录表也可以正常工作。一个品味imo的问题。 (不是我期望TS总是使用这个,因为他似乎没有在真正的数据库上工作。) – winkbrace

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表中删除记录。

要删除特定人员(本例中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