2012-11-30 35 views
1

的表格:外鍵或刪除觸發器?

SIGN_OBJECT: 
ID VARCHAR2(32) PRIMARY KEY, 
DESCRIPTION VARCHAR2(100), 
X NUMBER(10,3), 
Y NUMBER(10,3), 
... 
GEOMETRYID VARCHAR2(32) 

LAMPPOST_OBJECT: 
ID VARCHAR2(32) PRIMARY KEY, 
DESCRIPTION VARCHAR2(100), 
X NUMBER(10,3), 
Y NUMBER(10,3), 
... 
GEOMETRYID VARCHAR2(32) 

OBJGEOMETRY: 
GEOMETRYID VARCHAR2(32) PRIMARY KEY, 
GEOMETRY MDSYS.SDO_GEOMETRY, 
... 

有很多X_OBJECT表。不幸的是,模式設計者(以他們無限的智慧)沒有看到各種對象類型之間的交叉。我無法在不創造更多工作的情況下更改這些表格。

對於每個對象表,都會有一個觸發器在插入或更新之前創建相關的SDO_GEOMETRY值(GEOMETRYID是唯一的 - 它來自序列)。此時觸發器會調用一個包裝函數,該函數插入OBJGEOMETRY記錄並返回geometryid。

問題是,如果父記錄被刪除,我想OBJGEOMETRY子記錄也被刪除。

最初我以爲這可以用外鍵級聯刪除來完成,但當然FK需要父表中的主鍵 - 顯然這是行不通的。

但是,我發現實際上FK需要父表中的唯一約束。我可以使X_OBJECT.GEOMETRYID唯一,但是我發現問題是因爲GEOMETRYID尚未填充到父表中,但FK要求它存在。我不能在觸發器內部做到這一點(通過設置:NEW.GEOMETRYID),所以我必須先寫GEOMETRYID然後提交?我不確定,這有惡劣的代碼味道。

所以我錯了嗎?這是更適合刪除觸發器的情況嗎?或者是有什麼我失蹤。

謝謝。

+0

外鍵在被引用表中需要唯一的約束。它們不需要*主鍵*約束,儘管這是最常見的唯一約束。 –

回答

0

觸發器應該在插入或更新之前觸發,而不是之後。然後你可以設置:NEW.GEOMETRYID與你的包返回的值。

此外,外鍵指向錯誤的方式。它應該是 ALTER TABLE x_OBJECT ADD FOREIGN KEY(geometryid)REFERENCES objgeometry(geometryid);

因此,您需要一個刪除觸發器...

+0

是的,這是一個BEFORE觸發我的錯誤。上面更新。 – Richard

+0

外鍵是否正常工作? –

+0

這不是一個外鍵 - 它是一個刪除觸發器 - 正如你所說的那樣。 – Richard

1

如果在同一事務中同時插入OBJGEOMETRY和X_OBJECT行,則可以將FK設置爲​​DEFERRABLE INITIALLY DEFERRED

在將在COMMIT時間來評估的話,而不是當你運行INSERT聲明。

+0

知道的非常有用! – Richard