外键或删除触发器?

时间:2012-11-30 10:11:33

标签: oracle database-design triggers

表格:

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然后提交吗?我不确定,这有不好的代码味道。

我错了吗?这是一个更适合删除触发器的情况吗?或者有什么我想念的东西。

感谢。

2 个答案:

答案 0 :(得分:1)

如果在同一事务中同时插入OBJGEOMETRY和X_OBJECT行,则可以将FK设置为​​DEFERRABLE INITIALLY DEFERRED

在这种情况下,它将在COMMIT时进行评估,而不是在您运行INSERT语句时进行评估。

答案 1 :(得分:0)

触发器应在插入或更新之前触发,而不是在之后触发。然后,您可以使用包返回的值设置:NEW.GEOMETRYID。

此外,外键指向错误的方式。它应该是     ALTER TABLE x_OBJECT ADD FOREIGN KEY(geometryid)REFERENCES objgeometry(geometryid);

因此,您需要删除触发器...