在Oracle中实施类型化关系

时间:2016-04-29 00:26:46

标签: oracle database-design

考虑一下:

CREATE TABLE "RTCIS"."PERSON" 
 (  "ID" NUMBER(9,0) NOT NULL,
  "NAME" VARCHAR2(30) NOT NULL,
  "SEX" VARCHAR2(1) NOT NULL,
  "FATHERID" NUMBER(9,0) NULL,
  "MOTHERID" Number(9,0) NULL,
  CONSTRAINT CK_PERSON_SEX CHECK (SEX IN ('M', 'F')),
  CONSTRAINT PK_PERSON PRIMARY KEY (ID),
  CONSTRAINT FK_PERSON_FATHER FOREIGN KEY (FATHERID) REFERENCES PERSON(ID),
  CONSTRAINT FK_PERSON_MOTHER FOREIGN KEY (MOTHERID) REFERENCES PERSON(ID)
 );

insert into person select 1, 'Fred',    'M', null, null from dual;
insert into person select 2, 'Charlie', 'M',    1, null from dual;
insert into person select 3, 'Doris',   'F', null,    1 from dual;

底部的3个insert语句都可以正常执行。但是,我真正想要做的是强制MOTHERID始终指向一个人,其中SEX ='F',而FATHERID总是指向一个SEX ='M'的人。

这可以在没有触发器的情况下在ORACLE中完成吗?

2 个答案:

答案 0 :(得分:1)

它可以。不幸的是,没有约束(检查约束不能包含子查询),但具有物化视图。视图在提交时立即更新;行将被插入m.v.如果父母的性别不正确,但是m.v.有一个不可能的检查约束,不允许任何行存在。像这样的东西;你可以尝试这个概念。

create materialized view PERS_MV
   build immediate
   refresh fast on commit
   as select c.id
      from   person c join person p1 on c.fatherid = p1.id
                      join person p2 on c.motherid = p2.id
      where  p1.sex = 'F' or p2.sex = 'M';

alter table PERS_MV add constraint pers_mv_sex_ck (0 != 0);

答案 1 :(得分:1)

我在mathguy建议的物化视图中遇到了各种问题,所以在Oracle forum中发布了问题。

Barbara Boehmer提出了一种非常巧妙的方法(请注意,这不包括DDL以创建外键索引,但应添加它们):

public Dropdown mViewerTypeDropDown;
    void Start () {
        mDebug = (LRDebug)mScriptHolder.GetComponent<LRDebug> ();
        mScriptHolder=GameObject.Find ("ScriptHolder");
        mViewerTypeDropDown.captionText.text = PlayerPrefs.GetString ("Viewer Type","Generic Cardboard (Default)");

    }
//The Function attached to onvaluechanged listner
public void ViewerTypeChanged(int value)
    {

        mViwerTypeChange = value;

        switch (mViwerTypeChange) {
        case 0:
            mViewerType = "Generic Cardboard (Default)";
            break;
        case 1:
            mViewerType="VR ONE (Zeiss)";
            break;
        case 2:
            mViewerType="VR Goggles (Merge)";
            break;
        case 3:
            mViewerType="C1-Glass (Go4D)";
            break;
        case 4:
            mViewerType="Cardboard v1 (Google)";
            break;
        }

        PlayerPrefs.SetString("Viewer Type",mViewerType);
        PlayerPrefs.Save ();
    }