解決済み: USING 内の SELECT は、実際に重複した s_main_obj_id を生成しました。私はそれらが一意でなければならないと思った(uuid、しかし愚かな微調整で生成された)、しかしあなたが不可能を排除したとき... ;-)
Oracle 11g (R2 ではない) を使用して、ソース テーブル s の値をターゲット テーブル t にマージしたいと考えています。s と t の両方の PK はフィールド obj_id です。
私が使う:
MERGE
INTO target_table t
USING (SELECT ... AS s_main_obj_id, ... AS s_p1,
... AS s_p2, ... AS s_typ FROM source_table) s
ON (t.p1 = s.s_p1
AND t.p2 = s.s_p2
AND t.typ = s.s_typ)
WHEN NOT MATCHED
THEN
INSERT (obj_id,
p1,
p2,
typ)
VALUES (s_main_obj_id,
s_p1,
s_p2,
s_typ)
私は得る:
- 00000 - "一意の制約 (%s.%s) に違反しています"
*原因: UPDATE または INSERT ステートメントが重複キーを挿入しようとしました。
制約の ID は、ターゲット テーブルの obj_id を指します。
USING 内のSELECT で生成されるs_main_obj_idは確実に一意です。SELECT を取得して、結果を PK obj_id のターゲット テーブルに結合しようとしました。
SELECT * FROM (
SELECT ... AS s_main_obj_id, ... AS s_p1,
... AS s_p2, ... AS s_typ FROM source_table) s
JOIN target_table t
ON (t.obj_id = s.s_main_obj_id)
これにより、0の結果が得られます。
結果が得られない場合、MERGE はどのようにして重複キーを挿入しようとしているのでしょうか?
編集: ターゲット テーブルには、次の制約があります。
(エラーは SYS_C00138978 制約に言及しています)
そして、次のインデックス:
create table ステートメントは次のとおりです。
CREATE TABLE TARGET_TABLE_NAME
(
OBJ_ID VARCHAR2(40 CHAR) NOT NULL
, TYP VARCHAR2(1 CHAR)
, P1 VARCHAR2(40 CHAR)
, P2 VARCHAR2(40 CHAR)
, CONSTRAINT SYS_C00138978 PRIMARY KEY
(
OBJ_ID
)
ENABLE
)
LOGGING
TABLESPACE "USERS"
PCTFREE 10
INITRANS 1
STORAGE
(
INITIAL 65536
NEXT 1048576
MINEXTENTS 1
MAXEXTENTS 2147483645
BUFFER_POOL DEFAULT
);
CREATE UNIQUE INDEX TARGET_TABLE_NAME_OBJ_ID ON TARGET_TABLE_NAME (OBJ_ID ASC)
LOGGING
TABLESPACE "USERS"
PCTFREE 10
INITRANS 2
STORAGE
(
INITIAL 65536
NEXT 1048576
MINEXTENTS 1
MAXEXTENTS 2147483645
BUFFER_POOL DEFAULT
);