2026년 07월 18일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-01489 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-01489 result of string concatenation is too long 는?
ORA-01489 에러는 Oracle에서 문자열 연결(concatenation) 연산의 결과가 해당 데이터 타입의 최대 허용 길이를 초과할 때 발생합니다. VARCHAR2 타입은 최대 4,000바이트(또는 확장 모드에서 32,767바이트), CHAR 타입은 최대 2,000바이트까지만 허용되며, 이 한계를 넘는 순간 Oracle은 즉시 이 에러를 던집니다. 특히 대용량 데이터를 다루는 ETL 작업이나 동적 SQL을 생성하는 로직, 또는 여러 컬럼을 하나로 합치는 리포팅 쿼리에서 자주 마주치게 됩니다.
주요 발생 원인
1. VARCHAR2 최대 길이 초과 연결
가장 흔한 원인으로, 여러 VARCHAR2 컬럼 또는 문자열 리터럴을 || 연산자로 합칠 때 결과값이 4,000바이트를 초과하는 경우입니다. 예를 들어 주소, 설명, 메모 등 길이가 긴 컬럼들을 한꺼번에 이어 붙이는 쿼리에서 흔히 발생하며, 개발 단계에서는 테스트 데이터가 짧아 문제가 없다가 운영 환경에서 실제 데이터가 들어오면 터지는 경우가 많습니다.
2. PL/SQL 내 동적 SQL 문자열 누적
PL/SQL 블록에서 동적 쿼리를 문자열로 조립할 때, VARCHAR2 변수에 반복적으로 문자열을 덧붙이다 보면 32,767바이트 한계를 넘기는 상황이 발생합니다. 특히 루프 안에서 조건절이나 IN 절을 동적으로 쌓아가는 방식은 데이터 건수에 따라 예측하기 어렵게 문자열이 커지기 때문에 매우 위험합니다.
3. CLOB 대신 VARCHAR2를 잘못 사용하는 경우
대용량 텍스트 처리가 필요한 컬럼을 설계할 때 CLOB 대신 VARCHAR2를 사용하거나, 중간 처리 변수를 VARCHAR2로 선언한 경우에 발생합니다. 처음에는 데이터가 짧아 문제가 없어 보이지만, 시스템이 운영되면서 데이터가 점점 쌓이면 어느 시점에 에러가 폭발적으로 발생합니다. 이는 애초에 데이터 모델링 단계에서의 설계 실수에서 비롯되는 경우가 많습니다.
해결 방법
해결책 1: CLOB 타입으로 변환
연결 결과를 CLOB 타입으로 캐스팅하면 최대 4GB까지 처리할 수 있습니다.
-- 문제가 되는 쿼리 (VARCHAR2 한계 초과 시 ORA-01489 발생)
SELECT col_a || col_b || col_c AS combined_text
FROM large_text_table;
-- 해결책: TO_CLOB()으로 첫 번째 피연산자를 CLOB으로 변환
SELECT TO_CLOB(col_a) || col_b || col_c AS combined_text
FROM large_text_table;
-- 또는 CLOB 컬럼을 직접 선언하여 사용
DECLARE
v_result CLOB := EMPTY_CLOB();
BEGIN
SELECT TO_CLOB(col_a) || col_b || col_c
INTO v_result
FROM large_text_table
WHERE id = 1;
DBMS_OUTPUT.PUT_LINE(DBMS_LOB.GETLENGTH(v_result));
END;
/
해결책 2: SUBSTR로 문자열 길이 제한
비즈니스 요건상 정확히 잘라도 무방한 경우에는 SUBSTR 함수를 사용해 길이를 제한합니다.
-- SUBSTR을 사용하여 결과 길이를 안전하게 제한
SELECT SUBSTR(col_a || ' ' || col_b || ' ' || col_c, 1, 4000) AS combined_text
FROM large_text_table;
-- 길이 체크 후 조건 처리
SELECT
CASE
WHEN LENGTH(col_a) + LENGTH(col_b) + LENGTH(col_c) > 3990
THEN SUBSTR(col_a || col_b || col_c, 1, 3990) || '...'
ELSE col_a || col_b || col_c
END AS safe_combined
FROM large_text_table;
해결책 3: PL/SQL에서 CLOB 변수로 동적 SQL 처리
-- 잘못된 방법: VARCHAR2 변수에 동적 SQL 누적 (ORA-01489 위험)
DECLARE
v_sql VARCHAR2(32767);
BEGIN
v_sql := 'SELECT * FROM employees WHERE dept_id IN (';
FOR rec IN (SELECT dept_id FROM departments) LOOP
v_sql := v_sql || rec.dept_id || ','; -- 길이 한계 초과 위험
END LOOP;
v_sql := RTRIM(v_sql, ',') || ')';
EXECUTE IMMEDIATE v_sql;
END;
/
-- 올바른 방법: CLOB 변수 사용
DECLARE
v_sql CLOB := EMPTY_CLOB();
BEGIN
DBMS_LOB.CREATETEMPORARY(v_sql, TRUE);
DBMS_LOB.APPEND(v_sql, 'SELECT * FROM employees WHERE dept_id IN (');
FOR rec IN (SELECT dept_id FROM departments) LOOP
DBMS_LOB.APPEND(v_sql, TO_CLOB(rec.dept_id || ','));
END LOOP;
-- 마지막 콤마 제거 후 닫기
v_sql := SUBSTR(v_sql, 1, DBMS_LOB.GETLENGTH(v_sql) - 1) || ')';
EXECUTE IMMEDIATE v_sql; -- CLOB으로 EXECUTE IMMEDIATE 가능 (Oracle 12c+)
DBMS_LOB.FREETEMPORARY(v_sql);
END;
/
해결책 4: XMLAGG 또는 LISTAGG 대안 사용
-- LISTAGG는 VARCHAR2 반환이라 ORA-01489 발생 가능
SELECT dept_id,
LISTAGG(employee_name, ', ') WITHIN GROUP (ORDER BY employee_name) AS emp_list
FROM employees
GROUP BY dept_id;
-- 대안 1: XMLAGG를 사용하면 CLOB 형태로 반환
SELECT dept_id,
RTRIM(XMLAGG(XMLELEMENT(e, employee_name || ', ')
ORDER BY employee_name).GETCLOBVAL(), ', ') AS emp_list
FROM employees
GROUP BY dept_id;
-- 대안 2: Oracle 19c 이상에서 LISTAGG ON OVERFLOW TRUNCATE 사용
SELECT dept_id,
LISTAGG(employee_name, ', ' ON OVERFLOW TRUNCATE '...' WITH COUNT)
WITHIN GROUP (ORDER BY employee_name) AS emp_list
FROM employees
GROUP BY dept_id;
예방 방법
1. 데이터 모델링 단계에서 타입 선택 기준 수립
컬럼 또는 변수에 저장될 데이터의 최대 크기를 초기 설계 단계에서 반드시 검토하고, 합산 시 4,000바이트를 초과할 가능성이 있는 경우 처음부터 CLOB 타입으로 정의하는 정책을 조직 내 표준으로 만들어야 합니다. 특히 여러 컬럼을 연결하는 뷰(View)나 보고서 쿼리를 작성할 때는 최악의 시나리오 기준으로 길이를 계산하는 습관을 들이고, 코드 리뷰 체크리스트에 이 항목을 반드시 포함시켜야 합니다.
2. 개발 및 테스트 환경에서 경계값 데이터 테스트 의무화
개발 단계에서 짧은 더미 데이터만 사용하면 ORA-01489는 운영 환경에서만 나타나는 잠복 버그가 됩니다. 단위 테스트 시 반드시 각 문자열 컬럼을 최대 길이로 채운 경계값(boundary value) 데이터를 사용하고, CI/CD 파이프라인에 이를 자동화된 테스트 케이스로 등록해두어야 합니다. 또한 운영 DB의 실제 데이터 분포를 주기적으로 분석하여 특정 컬럼의 길이가 임계치에 근접하면 사전 알람을 받는 모니터링 체계를 구축하는 것이 좋습니다.
관련 에러
- ORA-06502:
PL/SQL: numeric or value error: character string buffer too small— PL/SQL 변수에 허용 크기보다 큰 값을 할당하려 할 때 발생하며, ORA-01489와 함께 자주 짝으로 등장합니다. - ORA-01704:
string literal too long— SQL 문 내에 직접 작성한 문자열 리터럴이 4,000바이트를 초과할 때 발생합니다. - ORA-22835:
Buffer too small for CLOB to CHAR or BLOB to RAW conversion— CLOB을 VARCHAR2로 암묵적으로 변환하려 할 때 크기 초과로 발생하며, CLOB 처리 시 함께 주의해야 합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.