Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Oracle:FK引用多个父表中的主键_Sql_Oracle_Foreign Key Relationship_Referential Integrity - Fatal编程技术网

Sql Oracle:FK引用多个父表中的主键

Sql Oracle:FK引用多个父表中的主键,sql,oracle,foreign-key-relationship,referential-integrity,Sql,Oracle,Foreign Key Relationship,Referential Integrity,在Oracle 10g中,是否可以为外键定义引用完整性约束以引用多个父表中的主键 例如: 部门经理 部门ID 10 11 十二, 亚太部 部门ID 13 14 十五 欧洲、中东和非洲部 部门ID 16 17 十八 电磁脉冲 EMP\u ID部门ID 500 11 501 15 我希望EMP.DEPT\u ID能够引用DEPT\u AMER、DEPT\u APAC&DEPT\u AMER中的一个部门ID。是否有一种定义引用完整性的方法来满足这一需求。所有3个表中的部门ID都是从一个公共序列生成的,

在Oracle 10g中,是否可以为外键定义引用完整性约束以引用多个父表中的主键

例如:

部门经理 部门ID
10
11
十二,

亚太部 部门ID
13
14
十五

欧洲、中东和非洲部 部门ID
16
17
十八

电磁脉冲 EMP\u ID部门ID
500 11
501 15

我希望EMP.DEPT\u ID能够引用DEPT\u AMER、DEPT\u APAC&DEPT\u AMER中的一个部门ID。是否有一种定义引用完整性的方法来满足这一需求。所有3个表中的部门ID都是从一个公共序列生成的,并且保证是唯一的


如果无法使用引用完整性约束,是否有更好的方法来维护此数据完整性?

在三个不同的表中有一个实体。最好的方法是将DEPT\u AMER+DEPT\u EMEA+DEPT\u APAC合并到一个名为DEPT的表中,该表具有新的字段DEPT\u类型(AMER或EMEA或APAC)。对于功能支持和性能来说,这是更好的选择


如果新部门在南极开张,你会怎么办?添加另一个表?不您只需添加另一个dept_类型。

您可以定义约束,但它不会执行您想要的操作。您将永远无法向emp表中添加任何内容,因为关键的DEPT_ID必须驻留在每个DEPT_表中


假设必须保留现有结构,最简单的方法是定义一个物化视图,将这些表合并到一个视图中。国际海事组织,这是一个有缺陷的实施。我会为DEPT_uuinfo创建一个表,其中包含一个拆分各种类型的列。

您不能定义这样的FK约束。 但您可以使用触发器验证数据完整性。 例如:

 CREATE OR REPLACE TRIGGER emp_check_dept_id_trg
    BEFORE INSERT OR UPDATE 
    on emp
    FOR EACH ROW
    DECLARE
      l_res NUMBER;
    BEGIN
      SELECT count(*) 
      INTO l_res
      FROM (
              SELECT dept_id FROM DEPT_AMER WHERE dept_id = :NEW.DEPT_ID
            UNION ALL
                SELECT dept_id FROM DEPT_APAC WHERE dept_id = :NEW.DEPT_ID
            UNION ALL
                SELECT dept_id FROM DEPT_EMEA WHERE dept_id = :NEW.DEPT_ID
          )
      ;
      IF l_res = 0 THEN
        raise_application_error(-20000, 'referential integrity violated');
      END IF;
    END;
    /

如果所有表中的字段都相同,那么我建议将此模型折射为单个表,并为遗留应用程序创建视图。
有时,这种设计用于分区,但Oracle会自动维护分区,而应用程序级分区是冗余的。

是什么阻止在多个父表中使用部门ID?实际上,南极洲的一个部门正是我派某人去的地方,他提出了一个包含多个父表的数据模型。你可以试试,但基于触发器的RI几乎从来都不是100%可靠的。您需要锁定DEPT_*行,以防止它们被其他会话删除,等等。没错。但是当模式无法更改时,例如由于外部应用程序的原因。还有哪些选择。