ORA-01427은 주로 서브쿼리에서 1건을 초과한 레코드가 나올 때 발생하는 에러입니다.
쿼리를 보면 이해가 빠를 것 같습니다.
TESTDB라는 테이블이 있고 아래와 같이 데이터가 입력되어 있습니다.
<TESTDB>
자, 이제 에러가 나는 쿼리문을 보겠습니다.
WITH TESTDB AS(
SELECT '20123153' CODE, '이승현' CODENM, 'Y' USE_YN FROM DUAL UNION ALL
SELECT '20156121' CODE, '박민서' CODENM, 'Y' USE_YN FROM DUAL UNION ALL
SELECT '20143328' CODE, '최유진' CODENM, 'Y' USE_YN FROM DUAL UNION ALL
SELECT '20167832' CODE, '김애신' CODENM, 'N' USE_YN FROM DUAL UNION ALL
SELECT '20134252' CODE, '김동매' CODENM, 'Y' USE_YN FROM DUAL
)
SELECT *
FROM TESTDB
WHERE CODE = (
SELECT CODE
FROM TESTDB
WHERE USE_YN='Y'
)
문제가 되는 부분은 여기입니다.
WHERE CODE = (
SELECT CODE
FROM TESTDB
WHERE USE_YN='Y'
)
TESTDB의 CODE는 서브쿼리의 CODE와 1:1 매칭으로 조건이 걸려있습니다.
하지만 서브쿼리의 레코드는 총 4건입니다.(USE_YN='Y'인 사람들) 즉 1:4가 된 셈이죠.
이런 경우 에러가 발생합니다.
그러면 어떻게 쿼리를 수정할 수 있을까요?
방법은 두 가지가 있습니다.
1) CODE = 에서 CODE IN 으로 변경
2) 서브쿼리에서 레코드가 단 건이 나올 수 있도록 조건절 추가 및 수정
먼저 "=" 연산자를 "IN" 절로 수정하는 방법입니다.
IN 절을 사용하면 조건을 포함하는 레코드를 모두 추출합니다.
따라서 서브쿼리의 USE_YN='Y'인 CODE를 만족하는 레코드를 모두 추출하게 되며 에러는 사라집니다.
WITH TESTDB AS(
SELECT '20123153' CODE, '이승현' CODENM, 'Y' USE_YN FROM DUAL UNION ALL
SELECT '20156121' CODE, '박민서' CODENM, 'Y' USE_YN FROM DUAL UNION ALL
SELECT '20143328' CODE, '최유진' CODENM, 'Y' USE_YN FROM DUAL UNION ALL
SELECT '20167832' CODE, '김애신' CODENM, 'N' USE_YN FROM DUAL UNION ALL
SELECT '20134252' CODE, '김동매' CODENM, 'Y' USE_YN FROM DUAL
)
SELECT *
FROM TESTDB
WHERE CODE IN (
SELECT CODE
FROM TESTDB
WHERE USE_YN='Y'
)
다음은 "=" 연산자를 그대로 사용하면서 서브쿼리의 레코드가 한 건이 나오도록 변경해주는 방법입니다.
TESTDB 테이블에 USE_YN='N'인 레코드는 한 건입니다.
따라서 서브쿼리의 레코드는 총 한 건이며 에러는 사라집니다.
WITH TESTDB AS(
SELECT '20123153' CODE, '이승현' CODENM, 'Y' USE_YN FROM DUAL UNION ALL
SELECT '20156121' CODE, '박민서' CODENM, 'Y' USE_YN FROM DUAL UNION ALL
SELECT '20143328' CODE, '최유진' CODENM, 'Y' USE_YN FROM DUAL UNION ALL
SELECT '20167832' CODE, '김애신' CODENM, 'N' USE_YN FROM DUAL UNION ALL
SELECT '20134252' CODE, '김동매' CODENM, 'Y' USE_YN FROM DUAL
)
SELECT *
FROM TESTDB
WHERE CODE = (
SELECT CODE
FROM TESTDB
WHERE USE_YN='N'
)