chr(0) in Oracle, PostgreSQL Issue 분석

privatekim·2025년 6월 9일

테스트 환경

  • Oracle : 19.20 RAC
  • postgreSQL : 13.18
  • SharePlex 12.0

문제 상황

Oracle to EDB로 데이터 마이그레이션 중
SharePlex로 정합성 체크 중 chr(0)에 대한 데이터가 in sync 처리가 되지 않음.

chr 함수


CHR returns the character having the binary equivalent to n as a VARCHAR2 value in either the database character set or, if you specify USING NCHAR_CS, the national character set.

For single-byte character sets, if n > 256, then Oracle Database returns the binary equivalent of n mod 256.


즉 입력된 정수 값에 해당하는 아스키코드의 문자를 반환하는 함수이다.

대표적으로 65를 입력하면 대문자 A를 반환하고 0은 n/a을 의미한다.

SYS@racdb1>select chr(65) from dual;

C
-
A

Oracle chr(0) 처리

Oracle에서 chr(0)은 null이 아니다.


SYS@racdb1> select chr(0), null from dual;

C N
- -

SYS@racdb1> select 'true' from dual where chr(0) is not null;

'TRU
----
true


SYS@racdb1> select length(chr(0)), lengthb(chr(0)), length(null), lengthb(null) from dual;

LENGTH(CHR(0)) LENGTHB(CHR(0)) LENGTH(NULL) LENGTHB(NULL)
-------------- --------------- ------------ -------------
             1               1

결과에서 볼 수 있듯, 표현되는 결과 값은 달라도 chr(0)은 not null로 인식되며, 1byte의 공간을 사용한다.

즉 chr(0)은 1byte공간에 아무런 값이 없는 데이터이다. 공백의 데이터도 없다는 뜻이다.

PostgreSQL chr(0) 처리


Character with the given code. For UTF8 the argument is treated as a Unicode code point.
For other multibyte encodings the argument must designate an ASCII character.
The NULL (0) character is not allowed because text data types cannot store such bytes.


PostgreSQL에서는 chr(0)을 취급하지 않는다.
chr(0)에 대해서 값을 처리 할 경우 다음과 같은 오류메시지를 확인할 수 있다.

splex=# select chr(0);
ERROR:  null character not permitted

SharePlex ORAtoPG chr(0)

SharePlex를 통헤 chr(0)의 값이 oracle에서 postgresql로 전송될 경우 다음과 같은 형태로 전송된다.

splex=# select 'true' from splex.temp where c1 = '';
 ?column?
----------
 true
 true
(2 rows)

splex=# select 'true' from splex.temp where c1 is not null;
 ?column?
----------
 true
 true
(2 rows)

splex=# select bit_length(''), char_length('');
 bit_length | char_length
------------+-------------
          0 |           0

oracle에서는 ''의 값은 null이지만, postgresql에서는 not null의 값이다.
그렇다고 해서 postgresql에서 ''는 oracle chr(0)과 달리 어떠한 공간도 차지하지 않는다.

SharePlex에서 chr(0)를 length 0의 문자('')로 치환하여 적용한 것으로 판단함
이러한 DBMS특징 때문에 SharePlex를 이용한 정합성 체크에 한계가 있어 계속해서 repair가 수행되는 문제가 발생한다.

0개의 댓글