Reputation: 2668
Based on an integer ID, how can one constrain two tables referencing a common table from including the same element already in the other table?
A basic table of, let's say personal information is created:
CREATE TABLE person (
id INTEGER PRIMARY KEY AUTOINCREMENT,
info VARCHAR(10)
);
Then two tables referencing person
is created:
CREATE TABLE special (
id INTEGER PRIMARY KEY,
skill VARCHAR(10),
FOREIGN KEY (id) REFERENCES person(id)
);
CREATE TABLE snowflake (
id INTEGER PRIMARY KEY,
meltingpoint DECIMAL,
FOREIGN KEY (id) REFERENCES person(id)
);
However, I want to constrain the two tables from including the same person.
So I thought something like this would do the trick, but SQLite3 gives syntax errors (near CHECK).
ALTER TABLE special ADD CHECK (
(SELECT COUNT(*) FROM snowflake WHERE snowflake.id = special.id) = 0
);
OR based on this answer
ALTER TABLE special ADD CHECK (
NOT EXISTS (SELECT 1 FROM snowflake WHERE snowflake.ID = special.ID)
);
How might this be achieved? Am I onto something or should an entirely different approach be taken?
Upvotes: 5
Views: 9797
Reputation: 180060
The documentation says:
The expression of a CHECK constraint may not contain a subquery.
So you have to use triggers:
CREATE TRIGGER no_snowflake_if_special
AFTER INSERT ON snowflake
WHEN EXISTS (SELECT * FROM special WHERE id = NEW.id)
BEGIN
SELECT RAISE(FAIL, "a special with the same ID already exists");
END;
-- same for special
Upvotes: 8
Reputation: 56938
You cannot use ALTER TABLE
to add a CHECK to a column.
You can only use ALTER TABLE
to ADD
a column which can then have a CHECK
constraint.
You cannot rename a column nor delete a column.
The easiest method would be to define the CHECK in the column when creating the table. If you have data that needs to be kept, then you will have to :-
Upvotes: 0
Reputation: 51900
You could have two foreign keys in 'person' to both 'special' and 'snowflake' and a check that only one of the keys has a value. Another solution could be to join 'special' and 'snowflake' into one table and have a check that only one of 'skill' or 'meltingpoint' is given.
Upvotes: 0