在oracle 10.2中使用外键更新表

时间:2012-08-02 08:22:15

标签: oracle oracle10g

我有一个表ROUTE_DETAILS,其中包含ROUTE_NUMBER列和ROUTE_NAME

我有另一个表格CUSTOMER_DETAILS,其中包含CUST_CODE列,CUST_NAMEROUTE_NUMBER。此处路由号是ROUTE_DETAILS的外键。

ROUTE_DETAILS是父表,CUSTOMER_DETAILS是子表。

ROUTE_DETAILS中的数据:

ROUTE_NUMBER        ROUTE_NAME
RN0001            ROUTE1
RN0002            ROUTE2
RN                ROUTE3

CUSTOMER_DETAILS中的数据:

CUST_CODE        CUST_NAME       ROUTE_NUMBER
CC0001         CUSTOMER1        RN0001
CC0002         CUSTOMER2        RN

现在的问题是,当我尝试从ROUTE_NUMBER更新ROUTE_DETAILS或从ROUTE_NUMBER更新CUSTOMER_DETAILS时,会显示错误:完整性约束违规子记录结果

查询是:

update ROUTE_DETAILS 
   set ROUTE_NUMBER = 'RN0003' 
 where ROUTE_NUMBER = 'RN'

当我尝试更新customer_details时,会发生同样的事情。

3 个答案:

答案 0 :(得分:2)

我看到的唯一选择是将FK约束更改为“DEFERRABLE”。

然后,您可以在提交数据时检查约束时更改单个事务中的两行:

update ROUTE_DETAILS set ROUTE_NUMBER ='RN0003' where ROUTE_NUMBER ='RN';
update CUSTOMER_DETAILS set ROUTE_NUMBER ='RN0003' where ROUTE_NUMBER ='RN';
commit;

有关如何更改FK约束的详细信息,请参阅手册。

如果您将约束设置为“INITIALLY IMMEDIATE”,则需要在运行更新之前运行set constraints deferred

修改,这是一个完整的示例:

设置表和约束:

create table route_details
(
 route_number varchar(20) not null primary key
);

create table customer_details
(
   cust_code varchar(20) not null primary key,
   route_number varchar(20) not null
);

alter table customer_details
  add constraint fk_route_number 
     foreign key (route_number)
     references route_details (route_number)
  deferrable
  initially immediate;


insert into route_details (route_number)
values ('RN0001');

insert into route_details (route_number)
values ('RN');

insert into customer_details (cust_code, route_number)
values ('CC0001', 'RN0001');

insert into customer_details (cust_code, route_number)
values ('CC0002', 'RN');

commit;

运行更新:

set constraints all deferred;

update ROUTE_DETAILS set ROUTE_NUMBER ='RN0003' where ROUTE_NUMBER ='RN';
update CUSTOMER_DETAILS set ROUTE_NUMBER ='RN0003' where ROUTE_NUMBER ='RN';
commit;

答案 1 :(得分:1)

是的,如果孩子正在引用该键值,则无法更新父主键。

此外,您无法将子级更新为具有不引用父表中主键值的外键值。

所以,你可以:

1)在进行更改时暂时放松约束,确保之后重新应用。

或者

2)删除子行,更新父行,然后使用新的外键值重新插入子项。

答案 2 :(得分:1)

对此有两点想法......

首先,您不应该更改主键的值,主键的重点是它不会更改。

但是,如果你必须做出这种改变,我有两种方法可以做到这一点。

  1. 在route_details中插入'RN0003'作为新行。然后更新所有受影响的客户然后删除RN行。所以:

    插入route_number值('RN0003','ROUTE3');

    更新customer_details设置route_number ='RN0003',其中route_number ='RN';

    从route_details中删除route_number ='RN';

  2. 使用此处所述的延迟密钥:

  3. http://www.orafaq.com/wiki/Foreign_key

相关问题