2

I'm working on an assignment which wants me to write some referential integrity constraints on a table. It asks me to ensure that every battle in Outcomes is also mentioned in Battles and to handle all violations by setting the referencing value to NULL.

I'm working with the following schemas

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

I'm trying to add the foregin key like this:

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

I get the following error:

SQL error:

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

I know this is because "Pearl Harbor" is in OUTCOMES but not in BATTLES, what I want to know is if there is some way to ignore that fact and set the foreign key anyway?

Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
Ben Glasser
  • 3,216
  • 3
  • 24
  • 41

2 Answers2

3

and to handle all violations by setting the referencing value to NULL.

That's impossible, since battle is part of the Outcomes's PK so it can't be NULL. Your data model is simply not constructed to handle a "battle-less" outcome.


If you were to change your model and remove the battle from child table's PK, then you could "fix" the data by:

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

At this point, you would be able to create the FK without causing a violation (FKs are only enforced on non-NULL fields).

Branko Dimitrijevic
  • 50,809
  • 10
  • 93
  • 167
1

You have to look for an option which prevents the check at the time of key creation, for Sql Server it would be WITH NOCHECK it:

Specifies whether the data in the table is or is not validated against a newly added or re-enabled FOREIGN KEY or CHECK constraint. If not specified, WITH CHECK is assumed for new constraints, and WITH NOCHECK is assumed for re-enabled constraints.

Tomek
  • 3,267
  • 2
  • 22
  • 23