2

我有一张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 路线1
RN0002 路线2
注册护士路线3

中的数据CUSTOMER_DETAILS

CUST_CODE CUST_NAME ROUTE_NUMBER
CC0001 客户1 RN0001
CC0002 客户 2 注册护士

现在的问题是当我尝试更新ROUTE_NUMBERROUTE_DETAILS更新ROUTE_NUMBERCUSTOMER_DETAILS显示错误:找到完整性约束违反子记录

查询是:

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

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

4

4 回答 4

3

我看到的唯一选择是将 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;
于 2012-08-02T08:32:02.823 回答
1

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

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

因此,您可以:

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

或者

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

于 2012-08-02T08:31:49.803 回答
1

对此有两个想法...

首先,您不应该更改主键的值,主键的全部意义在于它不会改变。

但是,如果您必须进行此更改,我知道有两种方法可以做到这一点。

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

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

    更新 customer_details 设置 route_number = 'RN0003' where route_number = 'RN';

    从 route_details 中删除 route_number = 'RN';

  2. 使用此处描述的延迟键:

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

于 2012-08-02T08:36:19.233 回答
0

参考行动包括ON UPDATE.

*CASCADE:删除或更新父表中的行,并自动删除或更新子表中匹配的行。ON DELETE CASCADE和均受ON UPDATE CASCADE支持。

所以你可以在你的外键ON UPDATE CASCADE上使用参考动作。

alter table customer_details
  add constraint fk_route_number 
     foreign key (route_number)
     references route_details (route_number)
     ON UPDATE CASCADE;

对于 NDB 表,ON UPDATE CASCADE不支持。

于 2021-08-27T00:00:51.763 回答