删除前检查约束

问题描述

我有一个与此问题非常相似的问题 here,但它是 12 年前提出的,我确信从那时起情况已经发生了变化。

基本上,我希望能够在删除之前检查外键约束。我不想只做尝试/捕获或回滚,因为我想将前端的信息呈现给用户,告诉他们他们需要做什么才能删除他们的项目”正在尝试删除

如果添加了新的约束,我希望它能够继续工作。

一个完美的世界中,我希望能够从依赖于被删除行的其他表中的行中取回主键列表。

解决方法

好吧,你为什么要让用户的事情复杂化?据我了解,您想通知他们在他们首先删除详细记录之前无法删除主记录。如果是这样,你为什么不让数据库为你做这件事(他们,就是这样)?提示:on delete cascade


这就是你现在所拥有的(一个非常简化的例子):

SQL> create table tmaster
  2    (id_mas      number constraint pk_mas primary key);

Table created.

SQL> create table tdetail
  2    (id_det      number constraint pk_det primary key,3     id_mas      number constraint fk_det_mas references tmaster (id_mas));

Table created.

SQL> insert all
  2    into tmaster values (1)
  3    into tmaster values (2)
  4    --
  5    into tdetail values (100,1)   -- references master 1
  6    into tdetail values (101,1)   -- references master 1
  7    into tdetail values (200,2)   -- references master 2
  8  select * from dual;

5 rows created.

删除详细信息存在的 master 将不起作用:

SQL> delete from tmaster where id_mas = 1;
delete from tmaster where id_mas = 1
*
ERROR at line 1:
ORA-02292: integrity constraint (SCOTT.FK_DET_MAS) violated - child record
found


SQL>

你必须

SQL> delete from tdetail where id_mas = 1;

2 rows deleted.

SQL> delete from tmaster where id_mas = 1;

1 row deleted.

SQL>

但是,正如我所说,让数据库工作。注意 create table tdetail 中的第 4 行:

SQL> create table tmaster
  2    (id_mas      number constraint pk_mas primary key);

Table created.

SQL> create table tdetail
  2    (id_det      number constraint pk_det primary key,3     id_mas      number constraint fk_det_mas references tmaster (id_mas)
  4                           on delete cascade);                             --> this

Table created.

SQL> insert all
  2    into tmaster values (1)
  3    into tmaster values (2)
  4    --
  5    into tdetail values (100,2)   -- references master 2
  8  select * from dual;

5 rows created.

好的,让我们删除 master(仅限 master):

SQL> delete from tmaster where id_mas = 1;

1 row deleted.

哇,好用!我不需要对它做任何事情

SQL> select * from tmaster;

    ID_MAS
----------
         2

SQL> select * from tdetail;

    ID_DET     ID_MAS
---------- ----------
       200          2

SQL>