我有一个与这里的问题非常相似的问题,但它是12年前提出的,我相信从那时起情况已经改变了。
基本上,我希望能够在删除之前检查外键约束。我不想只做try/catch或回滚,因为我想在前端向用户提供信息,告诉他们需要做什么才能删除他们试图删除的项目。
如果增加新的限制,我希望它能够继续向前发展。
在一个完美的世界里,我希望能够从其他表中依赖于被删除行的行中获取主键列表。
为什么要让用户的事情复杂化?据我所知,你想通知他们,在他们首先删除详细记录之前,不能删除主记录。如果是这样的话,你为什么不让数据库为你做这件事(他们,也就是说(?提示: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.
删除其详细信息存在的主机将不起作用:
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, 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(仅限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>