본문 바로가기

프로그래밍/이것저것 일하면서

오라클 PLS-00183 Too many bind variables 해결방법

반응형

오라클 PL/SQL 에러 - PLS-00183 발생

운영 중인 배치 프로그램에 다른 데이터베이스에서 데이터를 가져와 업데이트하는 이런 쿼리가 있었습니다. 일배치로 실행되며 등록/수정/삭제된 데이터를 PL/SQL BEGIN ~ END 사이에서 insert, update, delete문으로 만드는 동적 쿼리가 MyBatis로 작성되어 있었습니다.

<update id="updateDataList">
    BEGIN
    <foreach collection="dataList" item="item">
        UPDATE MY_TABLE
        SET
            COL1 = #{item.col1}
          , COL2 = #{item.col2}
          , COL3 = #{item.col3}
          , COL4 = #{item.col4}
          , COL5 = #{item.col5}
          -- .... 이런식으로 13개
        WHERE
            COND1 = #{item.cond1}
        AND COND2 = #{item.cond2};
    </foreach>
    END;
</update>

그런데 어느날 문득 데이터를 점검하다 보니 최종 실행된 일시가 무려 1년 전인 것을 발견했습니다. 매일 Gb 단위로 남는 로그파일을 샅샅히 뒤져보니 PLS-00183 라는 오류코드 단서를 찾을 수 있었습니다.

PLS-00183 too many bind variables

에러코드에 붙은 메시지를 읽어보면 무엇이 문제인지 단번에 유추할 수 있었습니다. 바인드 변수가 너무 많다는군요. 

업데이트 요청에서 오류가 발생하였고, 데이터 건수를 조회해보니 4934건이었습니다. 바인딩 변수가 15개이므로 

4934 * 15 = 74,010

PLS-00183 too many bind variables 발생 원인

명확하게 처리하기 위해 오라클에서 "PLS-00183" 에러코드를 확인해보았습니다.
바인딩하는 변수는 65535까지 허용한다고 합니다. 16비트입니다.

해결

다음과 같이 구글 guava 라이브러리에 포함된 Lists 유틸 클래스를 사용하여 리스트를 1000개씩 나누어 반복문으로 실행하였습니다.

// 수정 전
syncService.updateDataList(updateDataList);

// 수정 후 
List<List<Tenant>> lists = Lists.partition(updateDataList, 1000);
for (List<Tenant> itr : lists) {
    syncService.updateDataList(itr);
}

 

출처

이 오류 해결에는 아래 URL 자료를 참고하였습니다.

https://www.oraexcel.com/database-oracle-12cR2-PLS-00183/lang-ko

 

오라클12cR2 PLS-00183 too many bind variables

데이터베이스: 12c 출시 2 오류 코드: PLS-00183 설명: too many bind variables 원인: The library unit used more bind variables than permitted. (The current limit is 65535 bind variables in one library unit.) 조치: Reduce the number of bind v

www.oraexcel.com

 

반응형

개발자가 그리는 인스타툰 팔로우하세요!