CONSTRAINT检查远程相关表中的值(通过连接等)

luk*_*rys 20 postgresql database-design referential-integrity constraints foreign-keys

我想添加一个约束来检查相关表中的值.

我有3张桌子:

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
);
Run Code Online (Sandbox Code Playgroud)

(如果你想让我对FK施加约束,请告诉我.)

我想补充一个约束somethink_usr_rel,检查typerole("两个表走"),例如:

ALTER TABLE somethink_usr_rel
    ADD CONSTRAINT CH_sm_usr_type_check 
    CHECK (usr.role.type = 'SOME_ENUM');
Run Code Online (Sandbox Code Playgroud)

我尝试用JOINs 做但没有成功.知道如何实现它吗?

Erw*_*ter 21

CHECK约束目前无法引用其他表.手册:

目前,CHECK表达式不能包含子查询,也不能引用当前行的列以外的变量.

一种方法是使用@Wolph演示的触发器.

没有触发器的干净解决方案:添加冗余列并将它们包含在FOREIGN KEY约束中,这是强制执行参照完整性的首选.关于dba.SE的相关回答及详细说明:

另一种选择是"伪造"IMMUTABLE函数进行检查并在CHECK约束中使用它.Postgres将允许这一点,但要注意可能的后果.你最好做一个NOT VALID约束.细节:


Wol*_*lph 9

一个CHECK约束是不是一种选择,如果你需要连接.您可以创建一个引发错误的触发器.

看一下这个例子:http://www.postgresql.org/docs/9.1/static/plpgsql-trigger.html#PLPGSQL-TRIGGER-EXAMPLE

CREATE TABLE emp (
    empname text,
    salary integer,
    last_date timestamp,
    last_user text
);

CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
    BEGIN
        -- Check that empname and salary are given
        IF NEW.empname IS NULL THEN
            RAISE EXCEPTION 'empname cannot be null';
        END IF;
        IF NEW.salary IS NULL THEN
            RAISE EXCEPTION '% cannot have null salary', NEW.empname;
        END IF;

        -- Who works for us when she must pay for it?
        IF NEW.salary < 0 THEN
            RAISE EXCEPTION '% cannot have a negative salary', NEW.empname;
        END IF;

        -- Remember who changed the payroll when
        NEW.last_date := current_timestamp;
        NEW.last_user := current_user;
        RETURN NEW;
    END;
$emp_stamp$ LANGUAGE plpgsql;

CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
    FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
Run Code Online (Sandbox Code Playgroud)

  • 具有连接的示例将更适合此问题。 (3认同)