我正在尝试在表的一列上创建一个外键,指向另一个表的两列,但我似乎遇到了错误。
这可能吗:
ALTER TABLE table_a add CONSTRAINT table_a_table_b FOREIGN KEY
(table_a.id,false) REFERENCES table_b(table_b.id,some_boolean);
不应该允许table_a引用table_b中的实体,其中'some_boolean'为真。
答案 0 :(得分:2)
一种方法是将一个虚拟列some_bool
添加到table_a
,默认值为false
,然后使您的FK约束引用两列:
create table table_a ( id varchar, some_bool bool default false);
create table table_b ( id varchar, some_bool bool);
alter table table_b add constraint table_b_unique unique( id, some_bool);
ALTER TABLE table_a add CONSTRAINT table_a_table_b
FOREIGN KEY (id,some_bool)
REFERENCES table_b(id,some_bool);
答案 1 :(得分:1)
我自己找到了一个解决方案,但似乎这种方式也不干净':
我在两个表上都创建了两个CHECK CONSTRAINT。
CREATE FUNCTION isSomeBooleanSet(BIGINT) RETURNS BOOLEAN AS
'select some_boolean from table_b where id = $1'
LANGUAGE SQL IMMUTABLE
RETURNS NULL ON NULL INPUT;
ALTER TABLE table_a ADD CONSTRAINT
some_boolean_true_is_not_allowed CHECK (isSomeBooleanSet(table_b_id)=false);
CREATE OR REPLACE FUNCTION tableAReferenceToInvalidTableBEntity(BIGINT, BOOLEAN)
RETURNS BOOLEAN
AS 'select count(*)>1 from table_a inner join table_b on table_b.id = table_a.table_b_id where table_a.table_b_id = $1 and $2 = true;'
LANGUAGE SQL IMMUTABLE RETURNS NULL ON NULL INPUT;
ALTER TABLE table_b add CONSTRAINT table_a_cannot_realte_to_table_b_some_boolean_set CHECK (tableAReferenceToInvalidTableBEntity(id,some_boolean)=false);