먼저 EXISTS 와 NOT EXISTS가 무엇인지 살펴보자
EXISTS는 SQL에서 EXISTS(서브쿼리) 식으로 사용되며 서브쿼리의 값이 있을 때 true를, 없을 때 false를 반환한다.
NOT EXISTS는 EXISTS과는 반대로 NOT EXISTS(서브쿼리) 식으로 사용되며 서브쿼리의 값이 있을 때 false를, 없을 때 true를 반환한다.
EXISTS(SELECT * FROM TB_TEST WHERE 1=1)
= true
NOT EXISTS(SELECT * FROM TB_TEST WHERE 1=1)
= false
이런 식으로 반환이 된다는 것이다.
이걸 조건문에 사용해서 다른 곳에서 가져온 데이터와 기존에 저장되어 있는 데이터를 비교해 새로운 값만 INSERT를 할 수 있게 해준다.
예제 1 INSERT
예를 들면 T_TEST 라는 테이블이 있다고 가정해보자
TEST_NO | TEST_NM |
1 | TSET01 |
2 | TSET02 |
그 안에 이런 값이 있다면
INSERT INTO T_TEST
(TEST_NO, TEST_NM)
SELECT
TEST_NO
, TEST_NM
FROM
(SELECT 1 AS TEST_NO, 'TEST01' AS TEST_NM FROM DUAL
UNION ALL SELECT 3 AS TEST_NO, 'TEST03' AS TEST_NM FROM DUAL) T
WHERE NOT EXISTS(SELECT TEST_NO FROM T_TEST WHERE TEST_NO = T.TEST_NO);
조금 복잡하지만 이런 SQL문을 실행하게 된다면
TEST_NO 가 1인 값은 이미 테이블에 있으므로 TEST_NO가 3 인 것만 INSERT하게된다.
코드를 잠깐 살펴보자면
(SELECT 1 AS TEST_NO, 'TEST01' AS TEST_NM FROM DUAL
UNION ALL SELECT 3 AS TEST_NO, 'TEST03' AS TEST_NM FROM DUAL)
이부분은 내가 받아오는 데이터를 넣는 부분이다.
만약 itemList 라는 배열에 TEST_NO와 TEST_NM을 각각 testNo와 testNm으로 받아온다고 생각해보자
{
itemList : [
{
testNo : 1,
testNm : "test01"
},
{
testNo : 2,
testNm : "test02"
},
{
testNo : 3,
testNm : "test03"
},
]
}
이런 식으로 들어온 들어온 데이터가 xml에서 아래의 코드를 만나면
(
<foreach item="item" collection="itemList" separator="UNION ALL" >
SELECT #{item.testNo} AS TEST_NO, #{item.testNm} AS TEST_NM FROM DUAL
</foreach>
)
(SELECT 1 AS TEST_NO, 'TEST01' AS TEST_NM FROM DUAL
UNION ALL SELECT 2 AS TEST_NO, 'TEST02' AS TEST_NM FROM DUAL
UNION ALL SELECT 3 AS TEST_NO, 'TEST03' AS TEST_NM FROM DUAL)
사실상 위의 코드로 변하는 것이다.
위의 FROM DUAL는 임의의 데이터 혹은 계산결과를 출력할 때 쓰인다.
그다음 밖에 있는 SELECT 문을 살펴보면
SELECT
TEST_NO
, TEST_NM
FROM
(SELECT 1 AS TEST_NO, 'TEST01' AS TEST_NM FROM DUAL
UNION ALL SELECT 3 AS TEST_NO, 'TEST03' AS TEST_NM FROM DUAL) T
WHERE NOT EXISTS(SELECT TEST_NO FROM T_TEST WHERE TEST_NO = T.TEST_NO);
이라고 되어 있는데
SELECT
TEST_NO
, TEST_NM
FROM
(SELECT 1 AS TEST_NO, 'TEST01' AS TEST_NM FROM DUAL) T
WHERE NOT EXISTS(SELECT TEST_NO FROM T_TEST WHERE TEST_NO = T.TEST_NO);
UNION ALL 를 지우고 보면 조금 더 쉽다.
FROM DUAL 로 만든
TEST_NO | TEST_NM |
1 | TSET01 |
이라는 테이블의 TEST_NO와 T_TEST의 TEST_NO를 비교해서 DUAL 테이블에 값이 없는 것들만 뽑아 INSERT 하게 되는 것이다.
예제 2 UPDATE
반대로 값이 있는 것들만 UPDATE 시키는 것도 가능하다.
UPDATE T_TEST T
SET TEST_NM=
(SELECT TEST_NM
FROM
(SELECT
1 AS TEST_NO
, 'TEST00' AS TEST_NM
FROM DUAL) T2
WHERE T.TEST_NO = T2.TEST_NO)
WHERE EXISTS (
SELECT TEST_NO
FROM
(SELECT
1 AS TEST_NO
FROM DUAL)T2
WHERE T.TEST_NO = T2.TEST_NO);
이런 식으로 사용하면 된다.