2026년 07월 26일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-01704 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-01704 string literal too long 는?
ORA-01704 에러는 SQL 문장 내에서 문자열 리터럴(string literal)의 길이가 Oracle이 허용하는 최대값인 4,000바이트를 초과할 때 발생합니다. 즉, 작은따옴표(')로 감싸진 문자열 값이 너무 길어 Oracle 파서(parser)가 처리할 수 없을 때 나타나는 에러입니다. 주로 대용량 텍스트 데이터를 INSERT 또는 UPDATE 구문에서 직접 하드코딩하거나, 마이그레이션 작업 중 스크립트를 자동 생성할 때 자주 마주치게 됩니다.
주요 발생 원인
1. SQL 문장 내 직접 하드코딩된 장문의 문자열
가장 빈번한 원인으로, DBA나 개발자가 INSERT 문에 긴 텍스트를 직접 입력하는 경우입니다. Oracle SQL에서 단일 문자열 리터럴은 최대 4,000바이트까지만 허용되며, 이를 초과하면 즉시 ORA-01704가 발생합니다. 특히 외부 시스템에서 데이터를 받아 SQL 스크립트로 변환할 때, 변환 로직이 문자열 길이를 검사하지 않으면 이 문제가 빈번하게 발생합니다.
2. 데이터 마이그레이션 또는 ETL 스크립트 자동 생성
레거시 시스템에서 데이터를 Oracle로 이관하는 과정에서 자동 생성된 SQL 스크립트에 긴 CLOB/VARCHAR2 컬럼의 데이터가 그대로 포함되는 경우입니다. 마이그레이션 툴이 CLOB 타입의 데이터를 단순히 문자열 리터럴로 감싸서 출력하면, 해당 데이터의 길이가 4,000바이트를 넘는 순간 이 에러가 발생합니다. 자동화 스크립트에서는 사람의 눈으로 확인하기 어렵기 때문에 실수가 더 잦습니다.
3. PL/SQL 또는 동적 SQL 내 문자열 연결(Concatenation) 처리 오류
PL/SQL 블록이나 동적 SQL을 구성할 때 여러 문자열을 연결하더라도, 단일 리터럴 상수 자체가 4,000바이트를 넘으면 동일한 에러가 발생합니다. 예를 들어 EXECUTE IMMEDIATE로 동적 쿼리를 생성하는 과정에서 WHERE 조건이나 데이터 값이 매우 길어지는 경우가 이에 해당합니다. 이 경우 문자열 연결 자체의 결과가 아닌, 개별 리터럴 조각의 길이가 문제가 됩니다.
해결 방법
해결책 1: TO_CLOB() 함수를 활용한 분할 처리
가장 권장되는 방법으로, 긴 문자열을 4,000바이트 이하의 조각으로 나누고 TO_CLOB() 함수와 || 연산자로 연결합니다.
-- 잘못된 방법 (ORA-01704 발생)
INSERT INTO article_table (article_id, content)
VALUES (1, '이곳에 4,000바이트를 초과하는 매우 긴 문자열이 들어갑니다...(중략)...');
-- 올바른 방법: TO_CLOB()으로 분할 후 연결
INSERT INTO article_table (article_id, content)
VALUES (
1,
TO_CLOB('첫 번째 문자열 조각 (4000바이트 이하)') ||
TO_CLOB('두 번째 문자열 조각 (4000바이트 이하)') ||
TO_CLOB('세 번째 문자열 조각 (4000바이트 이하)')
);
COMMIT;
해결책 2: PL/SQL 변수를 활용한 바인딩 처리
PL/SQL 블록 내에서 CLOB 타입 변수에 데이터를 할당한 후, DML에서 해당 변수를 바인딩하여 사용합니다. 이 방법은 리터럴 제한을 우회하면서도 성능 면에서 우수합니다.
DECLARE
v_long_text CLOB;
BEGIN
-- CLOB 변수에 긴 텍스트를 분할하여 할당
v_long_text := '첫 번째 긴 텍스트 조각...';
v_long_text := v_long_text || '두 번째 긴 텍스트 조각...';
v_long_text := v_long_text || '세 번째 긴 텍스트 조각...';
-- CLOB 변수를 바인딩하여 INSERT
INSERT INTO article_table (article_id, content)
VALUES (2, v_long_text);
COMMIT;
DBMS_OUTPUT.PUT_LINE('데이터 삽입 완료: ' || DBMS_LOB.GETLENGTH(v_long_text) || ' 바이트');
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE('에러 발생: ' || SQLERRM);
END;
/
해결책 3: DBMS_LOB 패키지를 활용한 CLOB 쓰기
대용량 데이터를 다룰 때 가장 안전하고 효율적인 방법입니다. DBMS_LOB.WRITEAPPEND 또는 DBMS_LOB.APPEND를 사용하면 LOB 데이터를 조각조각 안전하게 삽입할 수 있습니다.
DECLARE
v_clob CLOB;
v_chunk1 VARCHAR2(4000) := '첫 번째 데이터 청크 (최대 4000바이트)';
v_chunk2 VARCHAR2(4000) := '두 번째 데이터 청크 (최대 4000바이트)';
v_chunk3 VARCHAR2(4000) := '세 번째 데이터 청크 (최대 4000바이트)';
BEGIN
-- 빈 CLOB로 레코드 초기 삽입
INSERT INTO article_table (article_id, content)
VALUES (3, EMPTY_CLOB())
RETURNING content INTO v_clob;
-- DBMS_LOB을 통해 데이터를 순차적으로 추가
DBMS_LOB.OPEN(v_clob, DBMS_LOB.LOB_READWRITE);
DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_chunk1), v_chunk1);
DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_chunk2), v_chunk2);
DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_chunk3), v_chunk3);
DBMS_LOB.CLOSE(v_clob);
COMMIT;
DBMS_OUTPUT.PUT_LINE('총 CLOB 길이: ' || DBMS_LOB.GETLENGTH(v_clob));
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE('에러: ' || SQLERRM);
END;
/
해결책 4: 애플리케이션 레벨에서 Bind Variable 사용
Java, Python 등 애플리케이션에서 PreparedStatement 또는 Bind Variable을 사용하면 문자열 리터럴 제한을 근본적으로 우회할 수 있습니다.
-- Java PreparedStatement 예시 (SQL 부분만 표기)
-- 리터럴 직접 입력 대신 바인드 변수(:1) 사용
INSERT INTO article_table (article_id, content) VALUES (:1, :2);
-- Python cx_Oracle 예시에서 사용하는 SQL
INSERT INTO article_table (article_id, content) VALUES (:article_id, :content)
-- (Python 코드에서 content 변수에 긴 문자열을 할당하여 execute 호출)
예방 방법
1. 컬럼 타입을 목적에 맞게 설계하고 CLOB/NCLOB 사용을 적극 활용
4,000바이트를 초과할 가능성이 있는 컬럼은 설계 단계에서부터 VARCHAR2 대신 CLOB 또는 NCLOB으로 정의해야 합니다. VARCHAR2(4000)의 한계를 명확히 인식하고, 게시글 본문, 로그 내용, XML/JSON 데이터 저장 컬럼은 반드시 LOB 타입으로 설계하세요. 또한 Oracle 12c 이상에서는 MAX_STRING_SIZE = EXTENDED 파라미터를 활용하면 VARCHAR2를 최대 32,767바이트까지 확장할 수 있으나, 이 경우에도 SQL 리터럴 제한(4,000바이트)은 여전히 적용되므로 근본적인 해결책은 아닙니다.
2. 마이그레이션 및 스크립트 생성 시 문자열 길이 검증 로직 의무화
데이터 마이그레이션 스크립트나 SQL 생성 툴을 개발할 때, 모든 문자열 값에 대해 4,000바이트 초과 여부를 자동으로 검사하고 TO_CLOB() 분할 처리를 적용하는 로직을 표준으로 수립하세요. 코드 리뷰 단계에서도 SQL 내 하드코딩된 긴 문자열이 있는지 점검하는 체크리스트 항목을 추가하면 실수를 효과적으로 예방할 수 있습니다.
관련 에러
- ORA-01460:
unimplemented or unreasonable conversion requested— LOB 데이터를 부적절한 타입으로 변환 시 발생하며 ORA-01704와 함께 나타날 수 있음 - ORA-22835:
Buffer too small for CLOB to CHAR or BLOB to RAW conversion— CLOB 데이터를 VARCHAR2로 변환할 때 크기 초과 시 발생 - ORA-06502:
PL/SQL: numeric or value error: character string buffer too small— PL/SQL에서 VARCHAR2 변수에 허용 크기를 초과하는 문자열을 할당할 때 발생하며, ORA-01704와 혼동되기 쉬운 에러 - ORA-00910:
specified length too long for its datatype— DDL에서 컬럼 크기를 잘못 지정했을 때 발생
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.