I would like to add a constraint that will check values from related table.
I have 3 tables:
CREATE TABLE somethink_usr_rel (
user_id BIGINT NOT NULL,
stomethink_id BIGINT NOT NULL
);
CREATE TABLE usr (
id BIGINT NOT NULL,
role_id BIGINT NOT NULL
);
CREATE TABLE role (
id BIGINT NOT NULL,
type BIGINT NOT NULL
);
(If you want me to put constraint with FK let me know.)
I want to add a constraint to somethink_usr_rel
that checks type
in role
("two tables away"), e.g.:
ALTER TABLE somethink_usr_rel
ADD CONSTRAINT CH_sm_usr_type_check
CHECK (usr.role.type = 'SOME_ENUM');
I tried to do this with JOIN
s but didn't succeed. Any idea how to achieve it?
CHECK
constraints cannot currently reference other tables. The manual:
Currently,
CHECK
expressions cannot contain subqueries nor refer to variables other than columns of the current row.
One way is to use a trigger like demonstrated by @Wolph.
A clean solution without triggers: add redundant columns and include them in FOREIGN KEY
constraints, which are the first choice to enforce referential integrity. Related answer on dba.SE with detailed instructions:
Another option would be to "fake" an IMMUTABLE
function doing the check and use that in a CHECK
constraint. Postgres will allow this, but be aware of possible caveats. Best make that a NOT VALID
constraint. See: