MERGE INTO의 목적은 어떤 테이블이나 뷰테이블을 해당 목표테이블과 합체(MERGE)하기 위한 목적인데요. 이걸 이용해서 데이터가 들어왔을 때 있는 데이터면 UPDATE하고, 없는 데이터면 INSERT하는 형태로도 쓰일 수 있습니다.
http://radiocom.kunsan.ac.kr/lecture/oracle/sql/merge.html
위에는 MERGE INTO를 잘 설명한 사이트네요.
여기서 조금 응용하면 원하는 대로 구현할 수 있습니다
USING 대상테이블/뷰 별칭
ON 조인조건
WHEN MATCHED THEN
UPDATE SET
컬럼1=값1
컬럼2=값2
WHEN NOT MATCHED THEN
INSERT (컬럼1,컬럼2,...)
VALUES(값1,값2,...);
MERGE INTO다음에 나오는 테이블명은 실제로 데이터가 들어가거나 업데이트 되는 테이블이구요.
USING 다음에 나오는 테이블명은 실제 데이터를 가져오거나 할 테이블이구요.
ON은 WHERE과 같은 조건문이죠.
WHEN MATCHED THEN은 매치되는게 있으면 UPDATE하라는 얘기구요.
WHEN NOT MATCHED THEN은 매치되는게 없으면 INSERT하게 되죠.
응용해봅시다.
[code]
MERGE INTO INSERTTABLE
USING DUAL
ON (ID = 1)
WHEN MATCHED THEN
UPDATE SET
DATA = 'idoori'
WHEN NOT MATCHED THEN
INSERT (ID, DATA)
VALUES (1, 'mudchobo')
[/code]
INSERTTABLE이라는 곳에 USING은 DUAL이라고 했는데 DUAL은 dual은 1개의 레코드 만을 갖는 dummy 테이블이라고 합니다. select 1 from dual해버리면, 1이 나오죠. 대상테이블은 필요없으니 dual로 설정합니다.
ON에서 ID = 1은 ID가 1인게 만약 있으면, DATA부분을 idoori로 업데이트하고, 없으면 mudchobo로 넣게 되는겁니다.
iBATIS에서는 아래와 같이 사용합니다.
Dao 소스
queryForObject("User.executeMerge", memberBean);
Xml
<statement id="executeMerge" parameterClass="MemberBean">
MERGE INTO CHEON_IBATIS_USER
USING ( 생략)
WHEN MATCHED THEN
UPDATE SET
생략
WHEN NOT MATCHED THEN
INSERT (
생략 )
VALUES (
생략 )
</statement>
문법:
MERGE INTO target_table_name
USING (table|view|subquery) ON (join condition)
WHEN MATCHED THEN
UPDATE SET col1 = val1[,col2 = val2]
WHEN NOT MATCHED THEN
INSERT(....) VALUES(....)
- INTO : DATA가 UPDATE 되거나 INSERT 될 TABLE 이름을 지정합니다
- USING : 대상 TABLE의 DATA와 비교한후 UPDATE 또는 INSERT할 대상이 되는
DATA의 SOURCE 테이블 또는 뷰를 지정
- ON : UPDATE나 INSERT를 하게 될 조건으로, 해당 condition을 만족하는 DATA
가 있으면 WHEN MATHCED 절을 시행하게되고 없으면 WHEN NOT MATCHED
이하를 실행하게 됩니다
* Primary Key 만 지정이 가능합니다. (090601, 카루딘 수정)
- WHEN MATCHED : ON 조건절이 TRUE 인 ROW에 수행할 내용
- WHEN NOT MATCHED : ON 조건절에 맞는 ROW가 없을 떄 수행할 내용
MERGE INTO ICOMCLOS
USING DUAL
ON (HOUSE_CODE ='"+house_code+"' AND COMPANY_CODE = '"+company_code+"' AND PART_CODE ='"+paramMap.get("part_code")+"' AND YEAR_MONTH ='"+paramMap.get("st_year")+"' || '"+paramMap.get("st_month")+"' )
WHEN MATCHED THEN
UPDATE SET
CLOSE_FLAG = 'Y',
CHANGE_DATE = '"+date+"', CHANGE_TIME = '"+time+"',
CHANGE_USER_ID = '"+user_id+"', CHANGE_USER_NAME_LOC = '"+name_loc+"'
WHEN NOT MATCHED THEN
INSERT (
HOUSE_CODE, COMPANY_CODE, PART_CODE, YEAR_MONTH, CLOSE_FLAG, STATUS,
ADD_DATE, ADD_TIME, ADD_USER_ID, ADD_USER_NAME_LOC
) VALUES(
'"+house_code+"','"+company_code+"','"+paramMap.get("part_code")+"','"+paramMap.get("st_year")+"'|| '"+paramMap.get("st_month")+"','Y','C',
'"+date+"','"+time+"','"+user_id+"','"+name_loc+"'
)
MERGE INTO AAAA A
USING ( SELECT EMP_NO, AUTH_CD
FROM BBBBB
WHERE EMP_NO = p_emp_no
AND AUTH_cd = p_auth_cd) B
ON (A.EMP_NO = B.EMP_NO AND A.AUTH_CD = B.AUTH_CD)
WHEN MATCHED THEN
UPDATE
SET A.REG_DATE = SYSDATE , A.REG_EMP_NO = p_reg_emp_no
WHEN NOT MATCHED THEN
INSERT (A.EMP_NO, A.AUTH_CD, A.MNGER_YN ,A.REG_DATE,A.REG_EMP_NO)
VALUES (p_emp_no,p_auth_cd,'N',SYSDATE,p_reg_emp_no);
if문으로 체크로직을 만들필요없이 이안에서 다처리하게된다 그전에는 있으면 카운트를 리턴해서
있으면, update
없으면, insert를 수행한다.
'SQL' 카테고리의 다른 글
ORACLE 10g 공백제거 정규표현식 (0) | 2013.11.04 |
---|---|
= null과 is null의 차이 (0) | 2011.09.28 |
SQL Row를 Col으로 변환 (0) | 2011.07.01 |