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
,检查type
中role
("两个表走"),例如:
ALTER TABLE somethink_usr_rel
ADD CONSTRAINT CH_sm_usr_type_check
CHECK (usr.role.type = 'SOME_ENUM');
Run Code Online (Sandbox Code Playgroud)
我尝试用JOIN
s 做但没有成功.知道如何实现它吗?
Erw*_*ter 21
CHECK
约束目前无法引用其他表.手册:
目前,
CHECK
表达式不能包含子查询,也不能引用当前行的列以外的变量.
一种方法是使用@Wolph演示的触发器.
没有触发器的干净解决方案:添加冗余列并将它们包含在FOREIGN KEY约束中,这是强制执行参照完整性的首选.关于dba.SE的相关回答及详细说明:
另一种选择是"伪造"IMMUTABLE函数进行检查并在CHECK
约束中使用它.Postgres将允许这一点,但要注意可能的后果.你最好做一个NOT VALID
约束.细节:
一个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)
归档时间: |
|
查看次数: |
10773 次 |
最近记录: |