한 번에 다른 서버에서 여러 데이터를 가져와서 DB에 밀어 넣는 작업이 필요했다.
<insert id="ADD_BOOK_INFO" parameterType="map">
<foreach item="item" collection="book_list" open="INSERT ALL" close="SELECT * FROM DUAL" separator=" " >
INTO BOOK_TBL(BOOK_KEY, WORK_TYPE, CODE, INSTALL_DATE)
VALUES (#{item,jdbcType=VARCHAR}, 0, #{code}, SYSDATE)
</foreach>
</insert>
처음엔 별생각 없이 위와 같이 INSERT ALL을 통해서 한 번에 입력을 하도록 했다.
추후 한번 넣는게 아니라 주기적으로 반복해야 한다는 소리를 듣고 다른 방식으로 바꿀 필요성을 느껴서 수정을 하기로 했다.
JAVA단에서 처리하고 싶었으나... 데이터가 많아서 속도나 부하가 무서워서 데이터를 비교하여 같은 값이 있으면 update를 하고 없으면 insert를 하도록 merge를 사용해서 수정하기로 하였다.
INSERT ALL을 MERGE INTO와 같이 쓸 수 있다면 좋겠지만 불행히도 같이 사용은 어려워 보여서 그냥 쿼리를 MERGE INTO문으로 바꾸기로 했다.
<update id="SET_BOOK_INFO" parameterType="map">
MERGE INTO BOOK_INFO_TBL A USING (
<foreach item="item" collection="book_list" open="" close="" separator="UNION" >
SELECT
#{item,jdbcType=VARCHAR} AS BOOK_KEY,
SYSDATE AS INSTALL_DATE,
0 AS WORK_TYPE,
#{code} AS CODE
FROM DUAL
</foreach>
) B ON (A.BOOK_KEY = B.BOOK_KEY)
WHEN MATCHED THEN
UPDATE
SET A.INSTALL_DATE = B.INSTALL_DATE,
A.WORK_TYPE = B.WORK_TYPE,
A.CODE = B.CODE WHEN
NOT MATCHED THEN
INSERT
(
BOOK_KEY,
INSTALL_DATE,
WORK_TYPE,
CODE
)
VALUES
(
B.BOOK_KEY,
B.INSTALL_DATE,
B.WORK_TYPE,
B.CODE
)
</update>
그래서 수정한 내용... 사실 실제 프로젝트와는 테이블이나 칼럼이 다르지만 대략 위와 비슷하게 수정하였다.
가져온 데이터를 반복문으로 임의의 데이터 row를 만들고 해당 테이블과 데이터를 동기화할 테이블과 BOOK_KEY를 비교하여 update 또는 insert 하도록 하였다.
[Oracle] TABLE ANALYZE 하기 (0) | 2023.02.14 |
---|---|
[Oracle] ORA-38104: ON 절에서 참조되는 열은 갱신할 수 없음 (0) | 2022.08.11 |
[Oracle] ORA-00054: 리소스가 사용 중이어서 NOWAIT가 지정되었거나 시간 초과가 만료된 상태로 획득합니다. (1) | 2022.03.22 |
[Oracle] PLS-00215 문자열 길이 제약은 (1 .. 32767)범위이어야 합니다. (0) | 2022.03.22 |
댓글 영역