Merge문 수행, insert 구문 오류 : ORA-00001: 무결성 제약 조건 위배 오류 0 8 15,044

by 게릴라 [SQL Query] [2016.08.05 15:18:46]


test.png (2,927Bytes)

안녕하세요. 오라클 입문자 질문입니다.
제목처럼 merge문 작성하여 수행시, insert문에서 "ORA-00001: 무결성 제약 조건(TARGET_TABLE_PK)에 위배됩니다"
가 발생합니다.

테이블 자체는 빈 테이블이라 오류 잡기가 여간 어려운 게 아니네요.

 

1)
SOURCE_TABLE 기준정보테이블
TARGET_TABLE 기준정보를 이용해서 데이터를 생성할 테이블

2)
각 테이블의 ID1~ID7이 해당 테이블의 KEY값, 이 KEY값으로 두 테이블 관계를 맺음

MERGE INTO TARGET_TABLE TARGET
                  USING SOURCE_TABLE SOURCE
                     ON (TARGET.ID1      = '조회값1'
                    AND TARGET.ID2      = '조회값2'
                    AND TARGET.ID3      = '조회값3'
                    AND TARGET.ID4      = '조회값4'
                    AND TARGET.ID5      = '조회값5'
                    AND TARGET.ID6      = '조회값6'
                    AND TARGET.ID7      = '조회값7'
                    AND TARGET.ID1 = SOURCE.ID1
                    AND TARGET.ID2 = SOURCE.ID2
                    AND TARGET.ID3 = SOURCE.ID3
                    AND TARGET.ID4 = SOURCE.ID4
                    AND TARGET.ID5 = SOURCE.ID5
                    AND TARGET.ID6 = SOURCE.ID6
                    AND TARGET.ID7 = SOURCE.ID7)
             
  WHEN MATCHED THEN //상기조건에 해당하는 값이 TARGET TABLE에 있으면 업데이트 수행 (에러 안남)

                  UPDATE SET TARGET.EXTRA1  =  'VAL1'
                            ,TARGET.EXTRA2 = 'VAL2'
                            ,TARGET.EXTRA3 = 'VAL3'
                            ,TARGET.EXTRA4 = 'VAL4'
                            ,TARGET.EXTRA5 = 'VAL5'
                            ,TARGET.EXTRA6 = 'VAL6'

                WHEN NOT MATCHED THEN // 상기조건에 해당하는 값이 없으면 데이터 삽입

                  INSERT (
                            TARGET.ID1        /*1 .키1 */
                           ,TARGET.ID2        /*2 .키2 */
                           ,TARGET.ID3        /*3 .키3 */
                           ,TARGET.ID4        /*4 .키4  */
                           ,TARGET.ID5        /*5 .키5  */
                           ,TARGET.ID6        /*6 .키6 */
                           ,TARGET.ID7        /*7 .키7  */
                           ,TARGET.EXTRA1             
                           ,TARGET.EXTRA2     
                           ,TARGET.EXTRA3
                           ,TARGET.EXTRA4         
                           ,TARGET.EXTRA5            
                           ,TARGET.EXTRA6           
                           )
                    VALUES (
                            '조회값1'                             
                           ,'조회값2'                            
                           ,'조회값3'                                                  
                           ,'조회값4'           
                           ,'조회값5'                          
                           ,'조회값6'                                            
                           ,'조회값7'                         
                           ,'VAL1'
                           ,'VAL2'
                           ,'VAL3'
                           ,'VAL4'
                           ,'VAL5'                            
                           ,'VAL6'                             
                           )

위 구문 실행시, TARGET_TABLE에 데이터가 없음에도 해당 오류가 발생합니다.
오류로그에 찍힌 SQL문 중에...INSERT문만 따로 떼어내서 실행하면 오류가 나지는 않습니다.

확인 한번 부탁드리겠습니다.
감사합니다.

by yozm0213 [2016.08.05 16:28:35]

무결성 제약 조건 오류면 insert 될때 pk로 지정된 값이 중복되어 들어가고 있는거 아닌지요?


by 게릴라 [2016.08.05 16:55:36]

빈테이블에 단건을 넣는데 무결성 에러가 나는거라...^^;

MERGE문 관련 문서를 보고 따라했는데 다른 방식으로 쿼리를 작성했더니

이상없이 수행되네요^^

답변 감사합니다.


by 마농 [2016.08.05 16:43:06]

머지구문 사용이 일반적이지 않네요? 이상합니다.
 1. 보통 소스를 이용해 타겟을 머지하거나
 2. 소스 없이 dual 을 이용해 입력값을 기준으로 타겟을 머지합니다.
그런데 위 구문은 이도 저도 아닌 짬뽕형이네요.
잘못 사용하고 계신 듯 하네요.


by 게릴라 [2016.08.05 16:49:33]

답변 감사드립니다.

구문을 아래와 같이 바꾸었더니 이상없이 실행됩니다.^^

USING
(
    SELECT *
    FROM SOURCE_TABLE
    WHERE ID1      = '조회값1'
       AND ID2      = '조회값2'
       AND ID3      = '조회값3'
       AND ID4      = '조회값4'
       AND ID5      = '조회값5'
       AND ID6      = '조회값6'
      AND ID7      = '조회값7'
) SOURCE
 
ON
(
    TARGET.ID1 = SOURCE.ID1
    AND TARGET.ID2 = SOURCE.ID2
    AND TARGET.ID3 = SOURCE.ID3
    AND TARGET.ID4 = SOURCE.ID4
    AND TARGET.ID5 = SOURCE.ID5
    AND TARGET.ID6 = SOURCE.ID6
    AND TARGET.ID7 = SOURCE.ID7
)

결국 제가 처음에 작성한 쿼리랑 같은 의미 같은데 왜 안되는지 원인은 모르겠네요...

뭐가 다른지 아직 모르겠습니다.

열심히 공부해야겠어요^^;;


by 마농 [2016.08.05 16:56:53]

처음 쿼리의 소스는 소스테이블 중 전체이구요.
변경 쿼리의 소스는 소스테이블 중 1건입니다.
처음 쿼리는 전체를 대상으로 동일값을 입력 처리하고 있구요. ==> 중복 발생
변경 쿼리는 1건을 대상으로 입력처리합니다.


by 게릴라 [2016.08.05 17:08:55]

MERGE INTO TARGET_TABLE TARGET
                  USING SOURCE_TABLE SOURCE
                     ON (SOURCE.ID1      = '조회값1'
                    AND SOURCE.ID2      = '조회값2'
                    AND SOURCE.ID3      = '조회값3'
                    AND SOURCE.ID4      = '조회값4'
                    AND SOURCE.ID5      = '조회값5'
                    AND SOURCE.ID6      = '조회값6'
                    AND SOURCE.ID7      = '조회값7'
                    AND TARGET.ID1 = SOURCE.ID1
                    AND TARGET.ID2 = SOURCE.ID2
                    AND TARGET.ID3 = SOURCE.ID3
                    AND TARGET.ID4 = SOURCE.ID4
                    AND TARGET.ID5 = SOURCE.ID5
                    AND TARGET.ID6 = SOURCE.ID6
                    AND TARGET.ID7 = SOURCE.ID7)
 ON절에서 조회값을 넘겨 해당 값이 소스테이블에 없으면

 해당 조회값을 인서트해야 하는게 아닌지요? 위 구문도 동일한 오류가 나더라구요...


by 마농 [2016.08.05 17:12:39]

INTO TARGET_TABLE TARGET   -- 요기(INTO)가 타겟이고
USING SOURCE_TABLE SOURCE  -- 요기(USING)가 원본이죠.
ON 절은 원본과 타겟의 연결조건이구요.
원본에 대한 조건을 주려면 ON 절이 아닌 USING 절에서 줘야죠.


by 게릴라 [2016.08.05 17:14:22]

아...제가 완전 잘못 이해하고 있었네요...

답변 정말 감사합니다!!!!

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입