안녕하세요.
이번 시간에는 SAP EAI PI/PO 솔루션을 사용하면서 경험했던
JDBC Adater의 SQL_DML 명령어중 MERGE INTO문의 사용법에 대해 설명해보려고 합니다.
우선, MERGE INTO문이란 Oracle과 Tibero에서 사용이 가능한 SQL 명령어 입니다.
MERGE INTO문의 기본 문법 (Merge into란?)
MERGE
INTO {table_name | View_name} a -- 테이블 또는 뷰
USING {table_name | View_name | Sub Query} b -- 테이블, 뷰, 서브쿼리
ON (a.column1 = b.column1) --조건절
WHEN MATCHED THEN --일치하는 경우 {UPDATE | DELETE}
UPDATE SET a.column2 = b.column2
DELETE
WHEN NOT MATCHED THEN -- 불일치하는 경우 INSERT
INSERT (a.column1, a.column2, a.column3)
VALUES (b.column1, b.column2, b.column3)
MERGE INTO의 경우 application에서 테이블에 명령어를 보낼 때,
일치하는 값이 있을 경우 UPDATE, DELET
일치하는 값이 없을 경우 INSERT
하는 조건을 넣어서 명령어를 보내고 싶을 때 사용하는 문법
위와같은 SQL 명령어는 SAP PI/PO에서는 주로 UPDATE_INSERT라는 명령어를 사용하지만
필요에 따라서는 MERGE INTO를 사용하는 경우도 있기 때문에 알아두면 좋을 것 같아 이렇게 공유하게 되었습니다.
때문에 MERGE INTO문은 SAP PI/PO 어떻게 처리해야 하는지에 대해 설명드리겠습니다.
먼저,OUT_BOUND(Source)와 IN_BOUND의 경우 아래와 같이 넣어줍니다.
(Source와 Target의 경우 DB to DB 통신을 가정하여 만들었습니다.)
1) OUT_BOUND(Source)
<?xml version="1.0" encoding="UTF-8"?>
<ns0:TEST_MERGE_INTO_OUT_MT xmlns:ns0="http://www.test.co.kr/TEST_MERGE_INTO">
<row>
<column1/>
<column2/>
<column3/>
</row>
</ns0:TEST_MERGE_INTO_OUT_MT>
2) IN_BOUND(Target)
<?xml version="1.0" encoding="UTF-8"?>
<ns0:TEST_MERGE_INTO_OUT_MT xmlns:ns0="http://www.test.co.kr/TEST_MERGE_INTO">
<Statement>
<TABLE_NAME action="">
<access/>
<key>
<column1/>
<column2/>
<column3/>
</key>
</TABLE_NAME>
</Statement>
</ns0:TEST_MERGE_INTO_OUT_MT>
두번째로, 위에 생성한 OUT_BOUND와 IN_BOUND를 활용하여 Mapping 처리를 해줍니다.

action의 경우 SQL_DML명령어를 사용하기 때문에 action에는 Constant 함수를 활용하여 SQL_DML이라는 값을 매핑시켜 줍니다.
access에는 MERGE INTO문을 사용하여 사용하고 싶은 용도에 맞게 아래와 같이 명령어를 기입해 줍니다.
MERGE INTO TABLE_NAME A
USING SELECT '$column1$, AS COLUMN1 FROM DUAL) B
ON (A.column1 = B.column1)
WHEN MATCHED THEN
UPDATE SET
A.COLUMN2 = '$COLUMN2$',
A.COLUMN3 = '$COLUMN3$'
WHEN NOT MATCHED THEN
INSERT
(A.COLUMN1,
A.COLUMN2,
A.COLUMN3)
VALUES
('$COLUMN1$',
'$COLUMN2$',
'$COLUMN3$')
-- '$COLUMN1$' 은 key에서 매핑되어진 column1 값
-- '$COLUMN2$' 은 key에서 매핑된 column2 값
-- '$COLUMN3$' 은 key에서 매핑된 column3 값
위와 같이 매핑을 하여 값을 받을경우 결과는 IN_BOUND에는 아래와 같은 결과가 나옵니다.
column1 = a
column2 = b
column3 = c
<?xml version="1.0" encoding="UTF-8"?>
<ns0:TEST_MERGE_INTO_IN_MT xmlns:ns0="http://www.test.co.kr/TEST_MERGE_INTO">
<Statement>
<TABLE_NAME action="SQL_DML">
<access>
<![CDATA[
MERGE INTO TABLE_NAME A
USING SELECT '$column1$, AS COLUMN1 FROM DUAL) B
ON (A.column1 = B.column1)
WHEN MATCHED THEN
UPDATE SET
A.COLUMN2 = '$COLUMN2$',
A.COLUMN3 = '$COLUMN3$'
WHEN NOT MATCHED THEN
INSERT
(A.COLUMN1,
A.COLUMN2,
A.COLUMN3)
VALUES
('$COLUMN1$',
'$COLUMN2$',
'$COLUMN3$')
]]>
</access>
<key>
<column1>a</column1>
<column2>b</column2>
<column3>c</column3>
</key>
</TABLE_NAME>
</Statement>
</ns0:TEST_MERGE_INTO_IN_MT>
MERGE INTO를 사용할 때 주의할 점!
MERGE INTO TABLE_NAME A
USING SELECT '$column1$, AS COLUMN1 FROM DUAL) B
ON (A.column1 = B.column1)
WHEN MATCHED THEN
UPDATE SET
A.column1 = '$COLUMN1$',
A.COLUMN2 = '$COLUMN2$',
A.COLUMN3 = '$COLUMN3$'
WHEN NOT MATCHED THEN
INSERT
(A.COLUMN1,
A.COLUMN2,
A.COLUMN3)
VALUES
('$COLUMN1$',
'$COLUMN2$',
'$COLUMN3$')
1. ON 조건절에 사용한 컬럼을 업데이트 할 경우 아래와 같은 오류가 발생한다.
'TABLE_NAME' (structure 'Statement'): java.sql.SQLException: ORA-38104: Columns referenced in the ON Clause cannot be updated: "A"."COLUMN1"
2. INSERT 조건절에서 INSERT값과 VALUE값의 항목이 다를경우 아래와 같은 오류가 발생한다.
'TABLE_NAME' (structure 'Statement'): java.sql.SQLSyntaxErrorException: ORA-00913: too many values