0

解決済み: 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)

私は得る:

  1. 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 
);
4

0 に答える 0