基于表值的Postgresql数据验证检查

时间:2019-04-25 08:18:49

标签: postgresql

我正在尝试创建一个跟踪电缆的数据库。每条电缆包含1个或多个芯线,这些芯线连接到两端的端子。表格中定义了每条电缆中的芯数。

| number_of_cores  | cable_id
|----------2-------|---1-----|

核心表格如下

cable_no   | from_id | core_mark | to_id
1001       |       1 | 1 Black   |     2
1001       |       2 | 1 White   |     4

我要创建一个检查,以防止插入另一个1001电缆芯。

在postgresql中有可能吗?

理想情况下,如果我尝试插入另一条具有另一个唯一芯号的1001电缆,则错误将类似于“电缆1001上使用的所有芯”

谢谢

2 个答案:

答案 0 :(得分:1)

我认为您需要的是诸如检查约束之类的东西。 (https://www.postgresql.org/docs/current/ddl-constraints.html

执行以下步骤:

1。正确创建一些表格

create table cable (cable_id int primary key, number_of_cores int);
create table core (core_id int primary key, cable_id int references cable (cable_id), from_id int, core_mark varchar (50), to_id int);

2。创建将验证插入内容的功能

create or replace function test_max_core_number(in_cable_id int)
 returns boolean
 language plpgsql
as $function$
declare
    res boolean := false;
begin
    if exists (
        select *
        from cable 
        where cable_id = in_cable_id
            and number_of_cores > (select count(*) from core where cable_id = in_cable_id )
    )
    then 
        res := true;
    end if;

    return res;
end;
$function$;

3。将约束添加到表中

alter table core 
add constraint cstr_check check (test_max_core_number(cable_id));

4。现在该进行一些测试了:)

insert into cable (cable_id, number_of_cores) values (1, 2), (2, 3);
insert into core (core_id, cable_id, from_id, core_mark, to_id)
values
    (1, 1, 1, '1 Black', 2)
    ,(2, 1, 2, '1 White', 4);

通常情况下现在一切正常。

5。现在是想要的错误!

insert into core (core_id, cable_id, from_id, core_mark, to_id)
values
    (3, 1, 3, '1 Green', 2);

希望这会有所帮助!

答案 1 :(得分:0)

我认为@Jaisus给出了很好的答案。

我只会在cable中添加交叉检查,以防止在number_of_cores中设置错误的值:

create or replace function test_cable_number_of_cores(in_cable_id int,in_number_of_cores int)
 returns boolean
 language plpgsql
as $function$
declare
    res boolean := false;
begin
    res := (in_number_of_cores>0 and (select count(cable_id) from core where cable_id=in_cable_id) <= in_number_of_cores);

    return res;
end;
$function$;


alter table cable add check(test_cable_number_of_cores(cable_id, number_of_cores));

-- ok
insert into cable(cable_id, number_of_cores) values (3, 2);
update cable set number_of_cores=3 where cable_id=3;

-- error
update cable set number_of_cores=1 where cable_id=1;