엑시엄이 보는 DB 세상
SQL 표준의 범위는 어디인가 0 2 3,321

by axiom 표준화 더블바이트 [2014.06.26]


데이터 길이와 타입, 이것은 모델링의 가장 기본적인 표준화 대상임이 분명하다. 그러나 대부분이 그 동일 타입, 길이 내의 데이터는 모두 100% 문제가 없을 것으로 생각하며 표준화 노력을 간과하기가 쉽다. SQL 표준도 반드시 필요한 이유가 바로 여기에 있다.

그럼 어떤 문제가 발생하는지 알아보자. 우리는 흔히 데이터 타입과 길이가 충족된다면 문제가 전혀 발생하지 않을 것으로 생각한다. 물론 필자도 그런 생각을 해왔다. 그러나 간혹 DBMS가 허용하는 문제에서 발생하게 될 수도 있다는 사실을 필자 본인도 몰랐다.

이 글에서 지금 말하고자 하는 내용은 단지 오라클 제품에 국한되는 것일지도 모르지만, 다른 DBMS에서는 이런 유사한 문제가 발생하지 않는다고는 누구도 보장할 수 없을 것이다.

오라클 DBMS는 좋은 제품임에 분명하다. 그러나 이번과 같은 경우는 분명 사용자들이 늘 사용해왔던 방법이 오라클 DBMS 업그레이드 시에 문제를 발생시킬 수 있음을 미처 생각하지 못한 것으로 보인다.

가장 기본적인 NLS(Native Language Support)를 맞추는 것에만 신경 쓰다 보니 전혀 다른 곳에서 문제가 발생하기도 한다. 이것은 외부의 표준화가 100%라고 하더라도 문제가 발생할 수 있음을 의미하며, 내부의 표준화 부재로 인한 특정 캐릭터에 대한 길이가 그 문제 발생의 원인이 되기도 한다.

필자는 DBMS 업그레이드 프로젝트에서 발견한 이슈 내용을 공유하고자 하는 의미에서 이 글을 정리해본다. 필자는 DBMS 업그레이드 프로젝트를 수행하게 됐고, 이를 평범한 오라클 업그레이드 프로젝트라고 생각했다. Oracle 9i에서 Oracle 11g로 업그레이드하는 것이었으나, 이곳에서 뜻하지 않는 이슈가 발생했다.

어느 날 SELECT ~ FROM WHERE LIKE '%~~%' SQL이 Oracle 9i에서는 결과 건수가 1건 이상이 나오는데 반해, Oracle 11g에서는 결과건수가 나오지 않는 사실을 알게 됐다.

무엇이 문제인가?

Oracle 11g에서는 이 SQL의 결과가 왜 안 나오는지를 확인했다. 요청한 SQL을 사용하다 보니 뭔가 폰트가 이상함을 알아챘다.

다른 프로젝트에서는 본 적이 없는 형태의 %였다. 자세히 보니, '%'와 '%'의 차이가 있음을 알아냈다. 즉, 일반적으로 우리가 사용하는 '%'가 아닌 좀더 큰 문자, 더블바이트였던 것이다. 이것을 소스에 넣어놓고 계속 사용하고 있었다고 한다.

  • SQL 비교 테스트 진행
  • -- Test 서버 환경
    -- OS 버전 : AIX 6.X
    -- DBMS 종류 : Oracle 11.2.0.3 외 기타 하위 버전
    
    SELECT dump('%'),
           dump('%')
      FROM DUAL;
    
    DUMP('%')          DUMP('%')
    ----------------   ----------------------
    Typ=96 Len=1: 37   Typ=96 Len=2: 163,165
    

위와 같이 싱글바이트(Single Byte)와 더블바이트(Double Byte)로 구분됨을 알 수 있다. 다시 다음의 SQL을 오라클 11.2.0.3과 이하 버전에서 테스트한 결과를 살펴보자.

  • 오라클 11.2.0.3에서 한 결과
  • WITH SQL1 AS
    ( SELECT 'aaa' c1 
        FROM DUAL
    )
    SELECT * 
      FROM SQL1
     WHERE c1 LIKE '%aaa%';
    
    no rows selected
    

위와 같이 결과는 나오지 않는다. 이것을 보면 더블바이트 '%'는 인식하지 못하는 것을 알 수 있다. 인식을 못하는 건지, 다르게 인식하는지는 바로 아래에서 설명하겠다.

  • 오라클 11.2.0.3보다 하위 버전에서 테스트한 결과
  • WITH SQL1 AS
    ( SELECT 'aaa' c1 
        FROM DUAL
    )
    SELECT * 
      FROM SQL1
     WHERE c1 LIKE '%aaa%';
    
    C1
    ---
    aaa
    

위와 같이 결과가 나오는 것을 알 수 있다. 하위 버전에서 '%'는 like의 와일드카드(Wild Card) 문자로 잘 인식하는 것을 확인했다.

지금까지의 결과를 바탕으로 오라클 버전마다 '%'의 인식 가능 여부에 차이가 있음을 알게 됐다.

원인에 대한 해결은 Oracle Reference에 있다

거의 모든 오라클 버전에서 like 부분을 찾아봤다. 그러나 더블바이트 '%'에 대한 내용은 찾을 수 없었다. 그러나 마지막 오라클 11.2.0.3에서야 해당되는 내용을 찾을 수 있었다.

내용은 바로 '%'는 더블바이트, '%'는 싱글바이트인데 11gR2에서는 더블바이트는 일반 캐릭터로 인식한다고 짧게 언급한 것을 볼 수 있었다.

즉, 오라클은 11gR2에서는 어떤 이유에서인지 더블바이트를 막기 시작한 것을 알 수 있었다. 이렇게 변경한 이유는 알 수 없지만 더블바이트 사용 시 일반문자로 인식하게 되므로 '%' 싱글바이트처럼 like %를 인식하지 않게 됐다는 것이다.

모든 오라클 11g 버전에서 동일한 결과가 나오는가?

그렇지 않다는 결과를 얻었다. 특이한 점은 OS별로 다른 결과를 얻을 수 있었고, 11g 버전별로 다른 결과를 얻을 수 있었다는 것이다.

리눅스와 윈도우의 경우 11gR2에서는 결과건수가 나오는 것이 확인됐다. AIX에서도 버전별로 상이한 결과를 얻을 수 있었다. 동일 AIX에서 오라클 11.2.0.1에서는 반대로 결과가 출력됐다.

표준의 범위는 어디인가?

SQL 표준, 즉 SQL 작성 표준이 필요한 것을 알 수 있는 부분이다. 너무 사소해서 간과하기 쉬운 부분일 수 있지만, 썩은 사과 하나가 같은 상자 속의 모든 사과를 썩게 만들 수도 있으므로 미리 선별해 나중에 모든 사과를 버리지 않기를 바란다.

- 강좌 URL : http://www.gurubee.net/lecture/2781

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

by 시골간아찌 [2014.07.02 21:49:58]

생각도 못한것이었네요..

좋은 정보 감사합니다..

 


by 꼬비 [2014.09.25 16:55:48]

좋은 정보 감사합니다!

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입