2017-08-10 107 views
0

我有一个像
表A的一个问题:
- TableBCId
表B:
- 标识
表C:
- 标识SQL外键,两个不同的表

我我正在寻找一种方法来创建一个外键表A,其中一个条目可以在表B或表C中。

示例条目:
表A:
- TableBCId:1
- TableBCId:2
表B:
- ID:1
表C:
- ID:2

我想避免如果可能的话:
- 两列表A
- 默认值
- 附加表
- 一个基座实体的创建是不可能

欢迎任何想法

+0

我想创建一个视图加入这两个表并使用它作为基地 - >但这将使我的表之间的链接可见。 –

+1

您能否使用[适当条款](https://en.wikipedia.org/wiki/Foreign_key)来重述您的问题?外键在表**中定义为**,而不是表**。包含外键的表称为**子表**。外键引用另一个表中的主键或唯一键。该表被称为**父表**。我真的不知道你问题中的哪个表是子表,哪一个是父表,哪一个包含主键或唯一键。 – krokodilko

+0

这是一个常见问题。只需使用Google搜索,就可以获得万亿次点击。人们不应该回答这个问题。 – philipxy

回答

0

您可以在您的Table_A上使用插入/更新触发器。

也许是这样的:

CREATE TRIGGER Table_a_trgr 
    BEFORE INSERT OR UPDATE 
    on Table_a 
    FOR EACH ROW 
    DECLARE 
     c_row NUMBER; 
    BEGIN 
     SELECT count(*) 
     INTO c_row 
     FROM (
       SELECT ID FROM table_b WHERE id = :NEW.TableBCId 
      UNION ALL 
       SELECT ID FROM table_c WHERE İd = :NEW.TableBCId 
     ) 
     ; 
     IF c_row < 2 THEN 
     raise_application_error(-20000, 'Error, Foreign Key'); 
     END IF; 
    END; 
    /
+0

这是一个不错的主意 –

+2

请注意,虽然触发器不是**限制**。它不会阻止某人从TABLE_B中删除TABLE_A中“引用”的记录。它甚至不能100%保证TABLE_B或TABLE_C中的相应记录存在于TABLE_A插入/更新提交的位置。 –

2

来实现这一要求的正常方法是用2列,2个外键约束和检查约束,以确保恰好填充柱(如果这是一个要求):

create table a 
    (... 
    , b_id references b 
    , c_id references c 
    , constraint <name> check ( (b_id is null and c_id is not null) 
          or (b_id is not null and c_id is null) 
          ) 
); 

你可以,如果有帮助你的用户界面,创建了该表,结合B_ID和C_ID成一个单一的列的视图。

但是你说你不想要2列,为什么?

+0

我的表格是自动创建和同步 - >这将是一个巨大的变化是我的代码): –

+0

@MarkusSchreiber请编辑和任何澄清到您的问题。 – philipxy

1

这很困难的原因是因为数据模型是错误的。一个外键仅引用一个表。一个表可以有多个外键,但每个都是分开的。除了别的,你怎么知道bc_id是以b.id还是c.id?对于这种情况

一种解释是,表A确实应该两个表,BA引用BCA引用C。或者A应该引用超类型表,其中BC是子类型。不知道实际的业务领域,很难确定。

无论如何,最小变化的路径是两列。

相关问题