Oracle PL/SQL 异常处理:删除父表数据,在异常处理中回滚后,仅恢复父表数据,而随父表的删除而自动删除的子表中对应的记录,无法恢复。

梨多情 2015-08-21 05:16:04

-- 【测试用表】
DROP TABLE child CASCADE CONSTRAINTS PURGE;
CREATE TABLE child(
c1 NUMBER CONSTRAINT child_c1_pk PRIMARY KEY,
c2 NUMBER
);
DROP TABLE parent CASCADE CONSTRAINTS PURGE;
CREATE TABLE parent(
c1 NUMBER CONSTRAINT parent_c1_pk PRIMARY KEY
);
INSERT INTO parent (c1) values (1);
INSERT INTO parent (c1) values (2);
INSERT INTO parent (c1) values (3);
ALTER TABLE child
ADD CONSTRAINT child_c2_parent_c1_fk
FOREIGN KEY(c2)
REFERENCES parent(c1);
INSERT INTO child VALUES(1,2);
SELECT * FROM child;
SELECT * FROM parent;
/*
【ORA-02292: 违反完整约束条件 (JSD1403.CHILD_C2_PARENT_C1_FK) - 已找到子记录】
若 child 表中已存在某记录的字段 c2=2 ,则由于该字段添加了外键约束,
外键关联了 parent 表的 c1 字段, 不能将 parent 表中 c1=2 的记录删除。
*/
-- 未定义异常处理器,自动回滚。
DECLARE
e_childExist EXCEPTION;
PRAGMA EXCEPTION_INIT(e_childExist, -2292);
BEGIN
DELETE FROM PARENT WHERE c1=2;
END;
/
-- 【遗留问题】:PL/SQL 删除外键关联的父表记录,回滚后子表记录无法恢复
-- 外键关联:子表数据无法回滚?
DECLARE
e_childExist EXCEPTION;
PRAGMA EXCEPTION_INIT(e_childExist, -2292);
BEGIN
DELETE FROM PARENT WHERE c1=2;
EXCEPTION
WHEN e_childExist THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE('错误类型:e_childExist');
END;
/
...全文
227 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
梨多情 2015-09-07
  • 打赏
  • 举报
回复
不好意思,忘了说明: “测试用表”部分的代码是在 MyEclipse SQL Editor 中执行的,会自动 commit 。 因为 PL/SQL 在 MyEclipse SQL Editor 中虽然能执行,但不会显示打印结果, 所以将 PL/SQL 代码在 SQL Plus 中执行可查看执行结果,SQL Plus 默认在 DML 之后需要 commt 。
卖水果的net 2015-08-27
  • 打赏
  • 举报
回复
这个不是 ORACLE 的问题 INSERT INTO child VALUES(1,2); 上面的语句执行后,你应该 commit 一下,但是你没的,所以 rollback 把这个语句也 一起回滚了。

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧