[플랫폼 종속 문제(데이터 이식, 마이그레이션)] ORA-12899: 열 string의 값이 너무 큽니다(실제:string, 최대:string)
■에러
ORA-12899 : 열 string의 값이 너무 큽니다 (실제 : string, 최대 : string)
이 문제의 대부분은 서로 다른 플랫폼간에 데이터를 교환할 때 발생한다.
(특히 Windows -> Unix 시스템으로 가져오는 프로세스의 경우)
・내보낸 데이터 가져오기
・데이터베이스 링크를 사용한 INSERT
・CHAR 유형을 사용한 문자열 조인
가 주요발생 타이밍이다.
■원인1
데이터를 제공하는 캐릭터 세트와 입력 대상의 데이터베이스 캐릭터 세트는
동일한 문자로도 바이트수가 다른 문자열을 사용한다. 대표적으로는 반각 가타카나이다.
Shift JTS의 경우 반각 가타카나는 'A6'x ~'DF'x로 1바이트로 저장할 수 있지만,
EUC-JP의 경우 '8E26'x ~ '8E5F'x로 길이는 2바이트가 된다.
마찬가지로 UFT-8이라면 3바이트, UTF-16이라면 2바이트가 된다.
■대응
근본적인 해결은 마이그레이션 대상의 테이블 정의를 변경한다.
이 에러가 나온다는 것은 테이블 정의의 열 정의가 바이트 시멘틱스 표기일 것이므로 그 바이트 사이즈를 크게 한다.
그 크기는 각 캐릭터 세트에서 한 문자의 최대 사이즈 x 캐릭터 수를 설정한다.
또는 캐릭터 시멘틱스로 열 정의 9i를 행한다.
■원인2
CHAR형을 사용한 캐릭터 라인 결합에 대해서 오해하고 있을 가능성이 있다.
예를 들어 CHAR(100)으로 정의된 컬럼(변수도 마찬가지)에 대해 'ABC'를 대입하면
컬럼은 'ABC' + 스페이스 97개가 된다.
CHAR(100)의 COL100열에 'ABC'를 설정한 후 UPDATE...SET COL=100 = COL100 || 'DEF'가 된다. ('||'는 문자열 연결)
CHAR(100)에 대입할 수 없기때문에 RTRIM 함수 등을 사용할 필요가 있다.
단, 'ABC_' + 'DEF' = 'ABC_DEF'를 기대해도 결과는 'ABCDEF'가 된다. ('_'는 공백 취급)
CHAR 유형의 문자열 조인 오류 예제 : 실제로 데이터 이행시에도 발생함.
SQL > CREATE TABLE CHAR_LEN(col100 CHAR(100));
테이블이 작성되었습니다.
SQL > INSERT INTO CHAR_LEN VALUES('ABC');
1행이 작성되었습니다.
SQL > UPDATE CHAR_LEN SET col100 = col100 || 'DEF';
UPDATE CHAR_LEN SET col100=col100 || ''DEF
*
행 1에서 오류가 발생했습니다. :
ORA-12899:열 "SYS"."CHAR_LEN"."COL100" 값이 너무 큽니다.(실제 : 103, 최대:100)
*
변수의 경우에도 마찬가지이지만 에러 메세지가 다른 PL/SQL의 경우에는
「ORA-06502: PL/SQL: 수치 또는 값의 에러 : 문자열 버퍼가 너무 작습니다. 가 발생했습니다.」 가 발생한다.
SQL > SET SERVEROUTPUT ON
SQL > DECLARE
2 vMoji100 CHAR(100);
3 BEGIN
4 vMoji100 := 'ABC';
5 dbms_output.put_line('vMoji Leng=' || lengthb(vMoji100 || 'DEF'));
6 vMoji100 := vMoji100 || 'DEF';
7 END;
8 /
vMoji Leng= 103 <- 103 바이트가 된다
declare
*
행1에서 오류가 발생했습니다. :
ORA-06502 : PL/SQL: 숫자 또는 값 오류 : 문자열 버퍼가 너무 작습니다. 발생
ORA-06512 : 행6
*