본문 바로가기
study_db

MERGE INTO 오류 - ORA-38101: INSERT VALUES 절에 부적합한 열이 있음

by developer_j 2023. 6. 27.
728x90
반응형

MERGE INTO 오류 - ORA-38101: INSERT VALUES 절에 부적합한 열이 있음

오류 발생 명령행: 71 열: 1
오류 보고 -
SQL 오류: ORA-38101: INSERT VALUES 절에 부적합한 열이 있음: "SCOTT"."A"."MBR_SEQ"

왜 이 오류가 났는지 처음에는 전혀 감이 잡히지 않았다.

서브쿼리만 떼다가 실행해봐도 문제가 없고, 다른 테이블로 만들었지만 똑같은 구조의 쿼리는 잘만 병합되었기 때문에..

 

▼ 요런 구조였는데

MERGE INTO TMP_MBR X
            USING (
                SELECT 
                    MBR.MBR_ID
                    , MBR.MBR_SEQ
                    , MBR.AGE
                FROM TB_MBR_MBR MBR
                WHERE MBR.MBR_ID = 'test01'
            ) Z
            ON (
                X.TMP_MBR_ID = Z.MBR_ID
                AND X.TMP_AGE = Z.AGE
            )
    WHEN NOT MATCHED THEN 
        INSERT
              (
                  TMP_MBR_ID
                  , TMP_AGE
              )
              VALUES
              (
                 Z.MBR_ID
                , ( /** 문제의 서브쿼리 */
                    SELECT 
                        CASE WHEN NVL(A.A_AGE,0) > 20 AND NVL(C.C_AGE,0) < 40
                                THEN TRUNC(ABS((NVL(B.B_AGE,0) - 1) / A.A_AGE)) + 1
                                ELSE 1
                           END TMP_AGE
                    FROM (
                        ...
                    ) A 
                    INNER JOIN (
                        ...
                    ) B ON A.MBR_ID = B.MBR_ID
                    INNER JOIN (
                        ...
                    ) C ON A.MBR_ID = C.MBR_ID
                    WHERE A.MBR_SEQ = Z.MBR_SEQ -- <- 이부분@@@@@@@@@@@
                  )
              );


계속 INSERT VALUES 절에 부적합한 열이 있다고 하니

테스트로 문제 발생원인이라고 생각되는 서브쿼리에, 서브쿼리문이 아닌 원시데이터를 넣어보기로 했다.

즉, TMP_AGE 의 값으로 서브쿼리문 대신 NUMBER 데이터 1을 넣어보았더니 정상 병합됨!

그래서 나는 데이터 형식이 문제였나? 라는 생각을 했고, 기존에 서브쿼리로 가져온 필드를 TO_NUMBER 함수를 이용해 NUMBER 형식으로 바꾸어줬더니 병합이 정상적으로 됐다.

 

 

이런식으로 한번 더 TO_NUMBER 함수로 감싸주는 것이다.


서브쿼리로 가져오면 숫자를 가져오더라도 문자형식으로 인식되는게 아닐까?

또한 해당 쿼리를 단독으로 돌렸을 때는 문제가 되지 않았지만, MERGE 구문 안에서는 문제가 발생하는 것을 보니

아마도 MERGE INTO 구문에서는 삽입할 데이터의 형식이 확실히 일치해야 되는 것 같다.

 

어떨 때는 TO_NUMBER 로 감싸주고, 어떨 때는 그냥 서브쿼리를 사용해도 된다고 생각하는 것보다는

편하게 어떤 경우에서든 숫자형 결과가 필요하다면 확실하게 한번 더 TO_NUMBER 로 감싸주는 게 좋겠다는 생각을 했다.

아, COUNT 쿼리 빼고 🙄

 

결론 : 서브쿼리로 가져 올 결과데이터가 NUMBER 형식이라면 한번 더 TO_NUMBER 로 감싸주기! 


+) 시도하다가 알게된 점.

TO_함수에 서브쿼리 사용 불가함.

SELECT TO_NUMBER(SELECT 1 FROM DUAL) FROM DUAL; -> 오류남
SELECT TO_CHAR(TMP) FROM (SELECT '1' AS TMP FROM DUAL); -> 오류 안남

SELECT TO_CHAR(SYSDATE) FROM DUAL; -> 오류안남
SELECT TO_CHAR(SELECT SYSDATE FROM DUAL) FROM DUAL; -> 오류남

즉 TO_함수를 사용하려면 FROM 절에서부터 이미 가지고 온 후여야 한다.

728x90
반응형