问题描述
我有一个与此问题非常相似的问题 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>