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 レコードを挿入してジオメトリ ID を返すパッケージ関数を呼び出します。

問題は、親レコードが削除された場合、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 に答える