๐จ์๋ฌ
ORA-01461: LONG ๊ฐ์ LONG ์ด์ ์ฝ์ ํ ๋๋ง ๋ฐ์ธ๋ํ ์ ์์ต๋๋ค
๊ฒ์ ๊ฒฐ๊ณผ LONG, CLOB ์ปฌ๋ผ์ ์ ๋ชป๋ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ผ๋ ค ํ ๋ ๋ฐ์ํ๋ ์๋ฌ๋ผ๊ณ ํ๋ค.
ํ์ง๋ง, ๋๋ ํ ์ด๋ธ์ LONG, CLOB ์ปฌ๋ผ์ด ์๊ณ BLOB์ด ์๋๋ฐ ์๋ฌ๊ฐ ๋ฐ์!!
โญ ์ ํํ ๊ธฐ์ค์ ๋ชจ๋ฅด๊ฒ ์ง๋ง ๋๋ ๊ธฐ์กด ํ ์คํธ ํต๊ณผํ ์ฝ๋์๋๋ฐ ๊ธธ์ด๊ฐ ๊ธด ๋ฐ์ดํฐ ๋ฑ๋กํ ๋์๋ง ํด๋น ์๋ฌ๊ฐ ๋ฌ๋ค!!
๐๊ธฐ์กด ์ฝ๋
MERGE INTO TB_GENR_DOC_MGMT target USING(
SELECT
#{boardId} AS boardId,
#{sno} AS sno, #{title} AS title,
#{contBlob, jdbcType=BLOB} AS cont
FROM DUAL
)
source ON (target.BOARD_ID = #{boardId} AND target.SNO = #{sno})
WHEN MATCHED THEN
UPDATE SET
TITLE = source.title,
CONT = source.cont,
UPD_DT = SYSDATE
WHEN NOT MATCHED THEN
INSERT (BOARD_ID, SNO, TITLE, CONT, REG_DT)
VALUES (source.boardId, source.sno, source.title, source.cont, SYSDATE)
๐ฅ์์ธ
- “MERGE๋ฌธ์์ BLOB ๋ฐ์ธ๋ ์ฒ๋ฆฌ ๋ฐฉ์” ๋๋ฌธ!!
- MERGE์ฒ๋ผ “WHEN MATCHED / WHEN NOT MATCHED” ๋ด๋ถ์์ source-select → target-update ๋ก ์ ๋ฌ๋๋ ๊ตฌ์กฐ์์๋ ๋๋ผ์ด๋ฒ๊ฐ ๋ฐ๋ก BLOB ๋ฐ์ธ๋๋ฅผ ์ง์ํ์ง ์์.
๐ก MERGE์์ BLOB ๋ฐ์ธ๋ ๋ฐฉ์
โ INSERT๋ UPDATE๋ง ํ ๋๋ ๊ด์ฐฎ์
UPDATE TB_GENR_DOC_MGMT SET CONT = ? WHERE BOARD_ID = ?;
์ฌ๊ธฐ์ ? ์๋ฆฌ์ BLOB ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ธ๋ฉํ๋ฉด, JDBC ๋๋ผ์ด๋ฒ๊ฐ "์, ์๋ BLOB ์ปฌ๋ผ์ ๋ฃ์ ๋ฐ์ดํฐ๊ตฌ๋" ํ๊ณ ์ ๋ฃ์ด์ค.
โ MERGE๋ ๊ตฌ์กฐ๊ฐ ๋ค๋ฆ
MERGE INTO TB_GENR_DOC_MGMT target USING ( SELECT ? AS cont FROM DUAL ) source ON (์กฐ๊ฑด)
WHEN MATCHED THEN UPDATE SET CONT = source.cont
WHEN NOT MATCHED THEN INSERT (CONT) VALUES (source.cont)
์ฌ๊ธฐ์ ?๋ ๊ทธ๋ฅ SELECT ์์ ์๋ ๊ฐ.
Oracle์ "์ด ? ๋ญ๋ก ํด์ํด์ผ ํ์ง?" ํ๊ณ ํท๊ฐ๋ ค๋ฒ๋ฆผ.
JDBC ๋๋ผ์ด๋ฒ๊ฐ ๊ทธ๊ฑธ ์ผ๋ฐ ๋ฌธ์์ด/์ซ์์ฒ๋ผ ์ทจ๊ธํ๋ ค๋ค๊ฐ → BLOB์ LONG์ฒ๋ผ๋ง ์ฒ๋ฆฌ ๊ฐ๋ฅ ์ด๋ผ๋ ์ ์ฝ ๋๋ฌธ์ ORA-01461 ์๋ฌ๋ฅผ ๋ฑ์.
๐ ํด๊ฒฐ ๋ฐฉ๋ฒ
EMPTY_BLOB() + RETURNING INTO ๋ฐฉ์ -> MERGE๋ฌธ ์์์ BLOB ์ปฌ๋ผ์ ์ง์ ๋ฐ์ธ๋ํ์ง ์๊ณ , EMPTY_BLOB()๋ก ์ด๊ธฐํ ํ RETURNING INTO๋ก InputStream ์ ์ก- MERGE ๋์ INSERT/UPDATE ๋ถ๋ฆฌ
- Oracle JDBC ๋๋ผ์ด๋ฒ ๋ฒ์ ํ์ธ -> ๋๋ผ์ด๋ฒ๋ง๋ค MERGE+BLOB ์ง์ ์์ค์ด ๋ค๋ฅด๋ฏ๋ก ์ต์ ๋ฒ์ ์ฌ์ฉ
โ 1. EMPTY_BLOB() + RETURNING INTO ๋ฐฉ์
๐จ java.sql.SQLException: ์ผ๋ถ ๋ฐํ ๋งค๊ฐ๋ณ์๋ง ๋ฑ๋ก๋์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์์ ํ์๋ ์๋ฌ ๋ฐ์ํจ!!
๐ฅ์์ธ
WHEN MATCHED / WHEN NOT MATCHED ๋ ๊ฐ์ RETURNING์ด ์กด์ฌ → Oracle์์๋ RETURNING INTO๋ ๋จ์ผ DML์ ํ๋๋ง ์ ์ฉ ๊ฐ๋ฅํ๋ฉฐ, JDBC์์๋ ๋ฐ๋์ CallableStatement + registerOutParameter ์ฌ์ฉ
๐ ํด๊ฒฐ๋ฒ
RETURNING์ ์์ ๊ณ , BLOB์ Java์์ ๋ณ๋๋ก SELECT ํ UPDATE.
๊ทผ๋ฐ ์ด๋ด ๋ฐ์ ๊ทธ๋ฅ insert, update ๋ฐ๋ก ํ๋๊ฒ ๋์์ ๊ทธ๋ ๊ฒ ํ๋ค..
<update id="updateNotice" parameterType="NoticeVO">
MERGE INTO TB_GENR_DOC_MGMT target
USING (
SELECT
#{boardId} AS boardId,
#{sno} AS sno,
#{title} AS title,
EMPTY_BLOB() AS cont,
TO_DATE(#{regDt}, 'YYYY-MM-DD hh24:Mi') AS regDt
FROM DUAL
) source
ON (target.BOARD_ID = #{boardId} AND target.SNO = #{sno})
WHEN MATCHED THEN
UPDATE SET
TITLE = source.title,
CONT = EMPTY_BLOB(),
REG_DT = source.regDt
RETURNING CONT INTO #{contBlob, jdbcType=BLOB}
WHEN NOT MATCHED THEN
INSERT (BOARD_ID, SNO, TITLE, CONT, VIEW_CNT, REG_DT, NTCE_END_DT)
VALUES (source.boardId, source.sno, source.title, EMPTY_BLOB(), SYSDATE)
RETURNING CONT INTO #{contBlob, jdbcType=BLOB}
</update>
โ 2. MERGE ๋์ INSERT/UPDATE ๋ถ๋ฆฌ
<insert id="insertNotice" parameterType="NoticeVO">
INSERT INTO TB_GENR_DOC_MGMT
(BOARD_ID, SNO, TITLE, CONT, REG_DT)
VALUES
(#{boardId}, #{sno}, #{title}, #{contBlob, jdbcType=BLOB}, SYSDATE)
</insert>
<update id="updateNotice" parameterType="NoticeVO">
UPDATE TB_GENR_DOC_MGMT
SET
TITLE = #{title},
CONT = #{contBlob, jdbcType=BLOB},
UPD_DT = SYSDATE
WHERE BOARD_ID = #{boardId} AND SNO = #{sno}
</update>