我有一个表ROUTE_DETAILS
,其中包含ROUTE_NUMBER
列和ROUTE_NAME
。
我有另一个表格CUSTOMER_DETAILS
,其中包含CUST_CODE
列,CUST_NAME
,ROUTE_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时,会发生同样的事情。
答案 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)
对此有两点想法......
首先,您不应该更改主键的值,主键的重点是它不会更改。
但是,如果你必须做出这种改变,我有两种方法可以做到这一点。
在route_details中插入'RN0003'作为新行。然后更新所有受影响的客户然后删除RN行。所以:
插入route_number值('RN0003','ROUTE3');
更新customer_details设置route_number ='RN0003',其中route_number ='RN';
从route_details中删除route_number ='RN';
使用此处所述的延迟密钥: