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

那我错了吗?这是否更适合删除触发器?还是我缺少什么。

谢谢。

4

2 回答 2

1

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

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

于 2012-11-30T10:30:17.330 回答
0

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

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

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

于 2012-11-30T10:46:30.680 回答