【发布时间】:2019-03-08 15:52:49
【问题描述】:
我有一个父表(配置文件),其中 profile_id 是主键,是 3 个不同子表的外键。 (s_profile, p_profile, c_profile)
现在,我想从表配置文件中删除一条记录,并想用 sysdate 更新子表中的“DELETED”列。
但是我的脚本不允许它说“外键违反 - 发现子记录”。
有解决办法吗?
【问题讨论】:
标签: plsql
我有一个父表(配置文件),其中 profile_id 是主键,是 3 个不同子表的外键。 (s_profile, p_profile, c_profile)
现在,我想从表配置文件中删除一条记录,并想用 sysdate 更新子表中的“DELETED”列。
但是我的脚本不允许它说“外键违反 - 发现子记录”。
有解决办法吗?
【问题讨论】:
标签: plsql
如果您希望在存在详细信息的情况下允许删除 master,那么该外键约束的目的是什么?
不管怎样,这里有一个例子说明你可以做什么;这是正确的方法吗,我不知道(我怀疑不是 - 再一次,它取消了引用约束的目的)。
创建两个表 - 主表及其详细信息:
SQL> create table profiles
2 (id_profile number primary key);
Table created.
SQL> create table s_profile
2 (id number primary key,
3 id_profile number constraint fk_s_pro references profiles (id_profile),
4 deleted date);
Table created.
SQL>
样本数据并尝试在存在详细信息时删除主数据:
SQL> insert into profiles values (1);
1 row created.
SQL> insert into s_profile (id, id_profile) values (100, 1);
1 row created.
SQL> delete from profiles where id_profile = 1;
delete from profiles where id_profile = 1
*
ERROR at line 1:
ORA-02292: integrity constraint (SCOTT.FK_S_PRO) violated - child record found
SQL>
在主表上创建一个触发器,删除外键值并设置日期:
SQL> create or replace trigger trg_bd_prof
2 before delete on profiles
3 for each row
4 begin
5 update s_profile s set
6 s.id_profile = null,
7 s.deleted = sysdate
8 where s.id_profile = :old.id_profile;
9 end;
10 /
Trigger created.
让我们再次尝试删除master:
SQL> delete from profiles where id_profile = 1;
1 row deleted.
SQL> select * From s_profile;
ID ID_PROFILE DELETED
---------- ---------- ----------
100 2018-10-03
SQL>
如果您想保存外键值,您可以更改详细信息表并添加另一列,例如 deleted_id_profile 并使用相同的触发器填充它。但是,如果 parent 不再存在并且您找不到任何有关它的信息,您会如何处理它?
【讨论】: