2017-08-10 89 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是子類型。不知道實際的業務領域,很難確定。

無論如何,最小變化的路徑是兩列。