web-dev-qa-db-ja.com

親テーブルと子テーブルのマルチテーブル挿入の使用

Oracleのマルチテーブル挿入ステートメントを使用して、(外部キー制約のある)親テーブルと子テーブルに挿入しても安全ですか?

最小限の例で、intoリストの親テーブルが子テーブルの前にある限り、機能することがわかりました。これに依存できますか、それとも制約を延期可能にする必要がありますか?

8
Isaac Kleinman

いいえ、これに依存することはできません。 SQLは手続き型ではなく宣言型であるため、ステートメント内では実行順序を保証できません。全体INSERT ALLステートメントは単一のステートメントと見なされます( doc )。1つのINSERTが別のステートメントの前にあることは保証できません。

定義により、INSERT FIRSTは、評価された条件を渡す最初のINTOを実行する必要があります。 INSERT ALLも同様に動作します。これはと表示されます

DROP TABLE T1;
CREATE TABLE T1 AS (SELECT 'a' c1, 0 c2, 0 c3 FROM dual WHERE 1=2);
INSERT ALL 
   WHEN mod(x,2)<>0 THEN INTO T1 VALUES ('a', x, mod(x,2)) 
   WHEN mod(x,2)=0 THEN INTO T1 VALUES ('b', x, mod(x,2)) 
   SELECT Level x FROM dual CONNECT BY Level <=20;
COMMIT;   
SELECT rowid, c1, c2, c3 FROM t1;

ただし、特定のプラットフォーム/バージョン/パッチセットで特定の動作を示すことができても、これが保証されるわけではありません。

Oracle-developer.net はそれを明示的に言っています:

iNSERT FIRSTステートメントの条件は、上から順に評価されます。 Oracleは、INSERT ALLステートメントではそのような保証をしません。

7
Leigh Riffel

アイザック、

OracleはINSERTの順序を保証しないため、これに依存することはできません。これを行う正しい方法は、先に述べたように、遅延外部キー制約を使用することです。

2
Narendra