SQL - 在具有不同列数的多个列上创建外键

时间:2016-09-05 20:26:39

标签: sql postgresql foreign-keys

我正在尝试在表的一列上创建一个外键,指向另一个表的两列,但我似乎遇到了错误。

这可能吗:

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'为真。

2 个答案:

答案 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);