ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 利用虚拟列实现虚拟删除的主外键约束

利用虚拟列实现虚拟删除的主外键约束

原创 Linux操作系统 作者:yangtingkun 时间:2010-07-11 23:30:53 0 删除 编辑

以前写过一篇文章,描述了当结论不从表中真正删除,而是利用DELETE_FLAG来表示删除时,无法再利用Oracle的主键键进行约束。不过前两天newkid版主巧妙了利用了11g的虚拟列来解决了这个问题。

这里给出完整的虚拟列实现的主子表DELETE_FLAG方式的外键约束。

利用11G的虚拟列实现复杂的外键约束:http://www.itpub.net/thread-1322611-1-1.html

无法利用主外键时控制主子表的并发访问(一):http://yangtingkun.itpub.net/post/468/453295

无法利用主外键时控制主子表的并发访问(二):http://yangtingkun.itpub.net/post/468/453397

无法利用主外键时控制主子表的并发访问(三):http://yangtingkun.itpub.net/post/468/453590

 

 

看一个简单的例子:

SQL> CREATE TABLE T_FATHER
  2  (ID NUMBER,
  3  NAME VARCHAR2(30),
  4  DELETE_FLAG VARCHAR2(1));

表已创建。

SQL> CREATE TABLE T_CHILDREN
  2  (ID NUMBER,
  3  FID NUMBER,
  4  F_FLAG AS (CAST (DECODE(DELETE_FLAG, 'Y', NULL, 'N') AS VARCHAR2(1))),
  5  DELETE_FLAG VARCHAR2(1));

表已创建。

表中包含了DELETE_FLAG,数据并不会真正的删除,当删除数据的时候,将DELETE_FLAG置为Y。显然普通的主外键无法满足这种设计的需要,因为将主表的记录删除的操作只是修改DELETE_FLAG列,而主表的记录仍然存在,因此子表新增的记录仍然可以参考主表已经产生的记录。

不过利用子表的虚拟列来建立外键越是,可以解决这个问题:

SQL> ALTER TABLE T_FATHER ADD                 
  2  PRIMARY KEY (ID, DELETE_FLAG);

表已更改。

SQL> ALTER TABLE T_CHILDREN ADD
  2  FOREIGN KEY (FID, F_FLAG)
  3  REFERENCES T_FATHER;

表已更改。

下面测试一下外键是否可以正常运作:

SQL> INSERT INTO T_CHILDREN (ID, FID, DELETE_FLAG) VALUES (1, 1, 'N');
INSERT INTO T_CHILDREN (ID, FID, DELETE_FLAG) VALUES (1, 1, 'N')
*
第 1 行出现错误:
ORA-02291:
违反完整约束条件 (TEST.SYS_C0011285) - 未找到父项关键字


SQL> INSERT INTO T_FATHER VALUES (1, 'A', 'N');

已创建 1 行。

SQL> INSERT INTO T_CHILDREN (ID, FID, DELETE_FLAG) VALUES (1, 1, 'N');

已创建 1 行。

SQL> INSERT INTO T_CHILDREN (ID, FID, DELETE_FLAG) VALUES (2, 1, 'Y');

已创建 1 行。

SQL> UPDATE T_FATHER
  2  SET DELETE_FLAG = 'Y'
  3  WHERE ID = 1;
UPDATE T_FATHER
*
第 1 行出现错误:
ORA-02292:
违反完整约束条件 (TEST.SYS_C0011285) - 已找到子记录


SQL> UPDATE T_CHILDREN
  2  SET DELETE_FLAG = 'Y'
  3  WHERE ID = 1;

已更新 1 行。

SQL> UPDATE T_FATHER
  2  SET DELETE_FLAG = 'Y'
  3  WHERE ID = 1;

已更新 1 行。

SQL> INSERT INTO T_CHILDREN (ID, FID, DELETE_FLAG) VALUES (3, 1, 'N');
INSERT INTO T_CHILDREN (ID, FID, DELETE_FLAG) VALUES (3, 1, 'N')
*
第 1 行出现错误:
ORA-02291:
违反完整约束条件 (TEST.SYS_C0011285) - 未找到父项关键字


SQL> INSERT INTO T_CHILDREN (ID, FID, DELETE_FLAG) VALUES (3, 1, 'Y');

已创建 1 行。

SQL> UPDATE T_FATHER
  2  SET DELETE_FLAG = 'N'
  3  WHERE ID = 1;

已更新 1 行。

SQL> UPDATE T_CHILDREN
  2  SET DELETE_FLAG = 'N'
  3  WHERE ID = 2;

已更新 1 行。

SQL> COMMIT;

提交完成。

可以看到,利用虚拟列配合主表的DELETE_FLAG建立的联合主外键,完全满足这种虚拟删除的主子表关系,可惜的是,只有11g采用虚拟列的功能,11g以前,必须利用触发器来构造真实的表列。

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-667760/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1964
  • 访问量
    11077250