2026년 06월 17일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-00920 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-00920 invalid relational operator 는?
ORA-00920 에러는 SQL 쿼리의 WHERE 절이나 조건식에서 잘못된 관계 연산자(Relational Operator)를 사용했을 때 발생하는 오류입니다. Oracle은 SQL 문법을 파싱하는 과정에서 비교 연산자가 올바르지 않거나, 연산자가 누락되었거나, 또는 완전히 잘못된 위치에 사용된 경우 이 에러를 반환합니다. 주로 WHERE 절, HAVING 절, CASE WHEN 조건식, JOIN ON 절 등 조건을 비교하는 모든 영역에서 발생할 수 있으며, 특히 동적 SQL을 생성하거나 복잡한 조건식을 작성할 때 자주 마주치는 에러입니다.
주요 발생 원인
1. 관계 연산자 오타 또는 잘못된 연산자 사용
Oracle SQL에서 허용되는 관계 연산자는 =, <>, !=, <, >, <=, >=, LIKE, IN, BETWEEN, IS NULL, IS NOT NULL 등으로 제한되어 있습니다. 프로그래머가 => (화살표 연산자, PL/SQL 명명 파라미터에서 사용)를 비교 연산자로 잘못 사용하거나, ==처럼 다른 언어에서 가져온 연산자를 그대로 사용하면 이 에러가 발생합니다. 특히 애플리케이션에서 동적으로 SQL을 조합할 때 조건 문자열을 잘못 연결하면 WHERE salary =>5000 처럼 잘못된 연산자가 만들어질 수 있습니다.
2. 조건절에서 연산자 누락 또는 조건식 불완전
WHERE 절에서 컬럼명과 값 사이에 비교 연산자를 아예 빠뜨리는 경우도 흔한 원인입니다. 예를 들어 WHERE employee_id 100 처럼 연산자 없이 컬럼과 값을 나란히 적거나, 조건식을 문자열로 조합하는 과정에서 연산자 부분이 빈 문자열이 되어버리는 경우가 실무에서 자주 발생합니다. 복잡한 동적 쿼리를 생성하는 Java, Python, PL/SQL 코드에서 조건 파라미터가 NULL이거나 비어 있을 때 연산자만 남겨두고 값이 사라지는 패턴도 이 에러를 유발합니다.
3. BETWEEN, IN, LIKE 등 복합 연산자의 잘못된 문법 사용
BETWEEN 연산자는 반드시 AND 키워드와 함께 사용해야 하고, IN 연산자는 괄호 안에 값 목록을 포함해야 하며, LIKE 연산자는 문자열 패턴과 함께 사용해야 합니다. 이러한 복합 연산자의 구성 요소를 빠뜨리거나 잘못된 위치에 배치하면 Oracle 파서가 올바른 관계 연산자를 찾지 못해 ORA-00920을 반환합니다. 예를 들어 WHERE salary BETWEEN 3000 처럼 AND 이후 값을 생략하거나 WHERE name LIKE 이후 패턴 문자열을 누락하는 경우가 이에 해당합니다.
해결 방법
원인 1 해결: 올바른 관계 연산자로 수정
잘못된 연산자를 Oracle이 인정하는 올바른 연산자로 교체합니다.
-- ❌ 잘못된 예 (=> 는 PL/SQL 명명 파라미터 전달 연산자)
SELECT employee_id, salary
FROM employees
WHERE salary => 5000;
-- ✅ 올바른 수정 (>= 사용)
SELECT employee_id, salary
FROM employees
WHERE salary >= 5000;
-- ❌ 잘못된 예 (== 는 Oracle SQL에서 지원하지 않음)
SELECT *
FROM employees
WHERE department_id == 10;
-- ✅ 올바른 수정 (= 사용)
SELECT *
FROM employees
WHERE department_id = 10;
-- ❌ 잘못된 예 (! 단독 사용 불가)
SELECT *
FROM employees
WHERE status ! 'ACTIVE';
-- ✅ 올바른 수정 (<> 또는 != 사용)
SELECT *
FROM employees
WHERE status <> 'ACTIVE';
-- 또는
SELECT *
FROM employees
WHERE status != 'ACTIVE';
원인 2 해결: 누락된 연산자 추가 및 동적 SQL 점검
조건절에 반드시 비교 연산자가 포함되어 있는지 확인하고, 동적 SQL 생성 로직을 검토합니다.
-- ❌ 잘못된 예 (연산자 누락)
SELECT *
FROM employees
WHERE employee_id 100;
-- ✅ 올바른 수정
SELECT *
FROM employees
WHERE employee_id = 100;
-- ❌ 동적 SQL에서 조건이 비어버린 경우 (PL/SQL 예시)
DECLARE
v_condition VARCHAR2(200) := '';
v_sql VARCHAR2(500);
BEGIN
-- 조건이 비어있어 WHERE 이후 아무것도 없는 상황 발생 가능
v_sql := 'SELECT * FROM employees WHERE ' || v_condition;
EXECUTE IMMEDIATE v_sql;
END;
/
-- ✅ 올바른 동적 SQL 처리 (조건이 없을 때 1=1 패턴 사용)
DECLARE
v_dept_id NUMBER := NULL;
v_sql VARCHAR2(500);
v_condition VARCHAR2(200) := '1=1';
BEGIN
IF v_dept_id IS NOT NULL THEN
v_condition := v_condition || ' AND department_id = ' || v_dept_id;
END IF;
v_sql := 'SELECT employee_id, first_name FROM employees WHERE ' || v_condition;
DBMS_OUTPUT.PUT_LINE('실행 SQL: ' || v_sql);
EXECUTE IMMEDIATE v_sql;
END;
/
원인 3 해결: 복합 연산자 문법 완성
BETWEEN, IN, LIKE 등의 복합 연산자를 올바른 형태로 완성합니다.
-- ❌ BETWEEN 잘못된 예 (AND와 상한값 누락)
SELECT *
FROM employees
WHERE salary BETWEEN 3000;
-- ✅ 올바른 BETWEEN 사용
SELECT *
FROM employees
WHERE salary BETWEEN 3000 AND 8000;
-- ❌ LIKE 잘못된 예 (패턴 누락)
SELECT *
FROM employees
WHERE first_name LIKE;
-- ✅ 올바른 LIKE 사용
SELECT *
FROM employees
WHERE first_name LIKE 'J%';
-- ❌ IN 잘못된 예 (값 목록 누락)
SELECT *
FROM employees
WHERE department_id IN;
-- ✅ 올바른 IN 사용
SELECT *
FROM employees
WHERE department_id IN (10, 20, 30);
-- ✅ 복합 조건 올바른 사용 예시 (실무 패턴)
SELECT e.employee_id,
e.first_name || ' ' || e.last_name AS full_name,
e.salary,
d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE e.salary BETWEEN 4000 AND 10000
AND e.hire_date >= TO_DATE('2015-01-01', 'YYYY-MM-DD')
AND e.job_id IN ('IT_PROG', 'SA_REP', 'FI_ANALYST')
AND e.first_name LIKE 'A%'
ORDER BY e.salary DESC;
예방 방법
1. SQL 정적 분석 도구 및 IDE 문법 검사 활용
SQL Developer, Toad, DBeaver 등의 IDE는 SQL 문법 오류를 작성 시점에 실시간으로 감지해 줍니다. 특히 동적 SQL을 생성하는 애플리케이션 코드에서는 반드시 단위 테스트를 통해 다양한 파라미터 조합으로 생성된 SQL을 DBMS_OUTPUT이나 로그로 출력하여 실행 전에 육안으로 검증하는 습관을 들여야 합니다. 또한 Oracle의 DBMS_SQL.PARSE를 활용하여 동적 SQL의 문법 유효성을 런타임에 검사하는 방어 코드를 추가하는 것도 좋은 방법입니다.
2. 동적 SQL 생성 시 바인드 변수와 표준 패턴 사용
동적 SQL을 문자열로 직접 조합하는 방식 대신 바인드 변수를 사용하면 연산자 오류뿐만 아니라 SQL Injection 위험도 동시에 줄일 수 있습니다. 조건이 가변적인 경우에는 WHERE 1=1 AND ... 패턴을 팀 내 공통 표준으로 채택하고, 각 조건 블록이 완전한 형태(컬럼 연산자 값)를 갖추도록 코드 리뷰 체크리스트에 포함시키는 것을 권장합니다.
관련 에러
- ORA-00904:
invalid identifier— 컬럼명이나 별칭이 잘못 지정된 경우로, ORA-00920과 함께 WHERE 절 오타 상황에서 자주 동반 발생합니다. - ORA-00936:
missing expression— 연산자 뒤에 비교 대상 값이나 표현식이 완전히 누락된 경우 발생하며, 조건절 불완전 문제에서 ORA-00920과 혼동될 수 있습니다. - ORA-00933:
SQL command not properly ended— SQL 문장의 구조적 오류로 인해 발생하며, 복합 연산자 문법 오류가 심한 경우 ORA-00920 대신 이 에러가 나타나기도 합니다. - ORA-01722:
invalid number— 숫자 컬럼에 문자 값을 비교할 때 발생하며, 연산자 자체보다는 피연산자 타입 불일치 문제입니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.