我有一个具有相当丰富架构的PostgreSQL [10.5]数据库。我有一个CUSTOMER_CONTACT
表,该表还被许多其他表引用。关系是delete cascade
和delete restrict
的混合。
如果delete restrict
表均未引用该客户联系人,我只想为用户提供删除该客户联系人的功能。如果其中有一个,则无法删除该客户联系人。
现在,总是通过用户界面提供删除,当我发现相关错误时,它将在运行时失败。
如何提前确定delete restrict
表中的任何一个是否引用了客户联系人,如果我知道不允许该操作,则可以隐藏用户界面删除操作?
除了依次手动检查每个表之外,还有其他方法吗?
答案 0 :(得分:1)
这个主意是个大“尾巴摇狗”的事情。您不是在根据业务逻辑来决定数据库结构,而是在根据业务结构来决定业务逻辑。
但是使用存储过程还是有可能的,例如:
首先,我将创建一些虚拟表:
create table CUSTOMER_CONTRACT (id int PRIMARY KEY );
create table CUSTOMER_CONTRACT_REF (id int PRIMARY KEY,
customer_id int REFERENCES CUSTOMER_CONTRACT(id));
现在到存储过程:
create or REPLACE function can_delete_contract(id int) returns boolean AS $$
BEGIN
delete from CUSTOMER_CONTRACT c
where c.ID = 1;
return true;
EXCEPTION
WHEN FOREIGN_KEY_VIOLATION then
return false;
END;
$$ LANGUAGE plpgsql;
如果发生异常,它将自动回滚。
现在要进行一些测试:
select can_delete_contract(1); // true
insert into CUSTOMER_CONTRACT values (1);
select can_delete_contract(1); // true
insert into CUSTOMER_CONTRACT values (1);
insert into CUSTOMER_CONTRACT_REF values(1, 1);
select can_delete_contract(1); // false