2

我正在处理一项希望我在表上编写一些参照完整性约束的任务。它要求我确保结果中的每场战斗也在战斗中提及,并通过将引用值设置为 NULL 来处理所有违规行为。

我正在使用以下模式

Battles(
    name VARCHAR(255) PRIMARY KEY, 
    date VARCHAR(255), 
)
Outcomes(
    ship VARCHAR(255),
    battle VARCHAR(255),
    RESULT VARCAHR(255),
    PRIMARY KEY(ship, battle)
)

我正在尝试像这样添加foregin键:

alter table outcomes 
add foreign key (battle) 
references battles(name) 
on delete set null 
on update cascade;

我收到以下错误:

SQL error:

ERROR:  insert or update on table "outcomes" violates foreign key constraint "outcomes_battle_fkey"
DETAIL:  Key (battle)=(Pearl Harbor 

我知道这是因为“珍珠港”在 OUTCOMES 但不在 BATTLES 中,我想知道是否有某种方法可以忽略这一事实并设置外键?

4

2 回答 2

3

并通过将引用值设置为 NULL 来处理所有违规行为。

这是不可能的,因为battle它是 PK 的一部分,Outcomes所以它不能为 NULL。您的数据模型根本不是为了处理“无战斗”结果而构建的。


如果您要更改模型并battle从子表的 PK 中删除,那么您可以通过以下方式“修复”数据:

UPDATE Outcomes SET battle = NULL
WHERE battle NOT IN (SELECT battle FROM Battles)

此时,您将能够创建 FK 而不会导致违规(FK 仅在非 NULL 字段上强制执行)。

于 2012-11-03T23:23:18.167 回答
1

您必须寻找一个选项,以防止在创建密钥时进行检查,对于 Sql Server,它会是WITH NOCHECK

指定是否针对新添加或重新启用的 FOREIGN KEY 或 CHECK 约束验证表中的数据。如果未指定,则假定 WITH CHECK 用于新约束,而 WITH NOCHECK 假定用于重新启用的约束。

于 2012-11-03T23:14:13.853 回答