表格:
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 :(得分: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);
因此,您需要删除触发器...