postgres检查外表列

时间:2014-03-11 11:30:36

标签: postgresql constraints

是否可以创建支票说:

"在computer_system中,检查ram(来自ram_table)是否与ram_type(来自motherboard_table)匹配"

我已经遍布google和stackoverflow,而且我已经读过它了“不可能”#39;在支票中引用外国表栏?但是有没有解决办法,或者我的逻辑有何缺陷? 任何帮助表示赞赏!

(编辑相关代码)

create table computer_system(
    system_id int primary key,
    ram int not null references ram(ram_id),
    cpu int not null references cpu(cpu_id),
    mb int not null references motherboard(mb_id),
    case int not null references computer_case(case_id),
    graphics int references gfx(gfx_id)
);

create table motherboard(
    mb_id int primary key,
    ram_type varchar(10) not null,
    socket varchar(10) not null,
    form_factor varchar(30) not null,
    ob_gfx boolean default(false)
)

create table ram(
    ram_id int primary key,
    speed int not null,
    size int not null,
    type varchar(10) not null
)

1 个答案:

答案 0 :(得分:3)

在PostgreSQL中使用CHECK约束不能执行此操作。

(理论上PostgreSQL可以允许这样做,但它需要在幕后创建触发器以检查依赖表,并且它不知道如何发现和证明关系)。

您需要在BEFORE INSERT OR UPDATE上创建computer_system触发器。触发器必须运行一个查询,该查询将获取rammotherboard中的相应行,并比较它们的type值。

像未经测试的东西:

CREATE OR REPLACE FUNCTION ram_type_matches() RETURNS trigger AS $$
DECLARE
    mb_ram_type text;
    ram_ram_type text;
BEGIN
    mb_ram_type  := (SELECT type FROM ram WHERE ram_id = NEW.ram)
    ram_ram_type := (SELECT ram_type FROM motherboard WHERE mb_id = NEW.mb)
    IF mb_ram_type <> ram_ram_type THEN
      RAISE EXCEPTION 'Mismatch between motherboard RAM type % and selected module type %', mb_ram_type, ram_ram_type;
    END IF;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER ram_type_matches_tg
BEFORE INSERT OR UPDATE ON computer_system
FOR EACH ROW EXECUTE PROCEDURE ram_type_matches();

严格来说,您还应该在ON UPDATEmotherboard上创建ram个触发器,以防止在创建记录后更改类型值。