아래 결과를 이해하는 것이 목표

SELECT DATA
     , TRANSLATE (DATA, ' 1234567890', ' ') AS "숫자만제거"
     , TRANSLATE (DATA, '1234567890'||DATA, '1234567890') AS "숫자만남기기"
     , TRANSLATE (LOWER(DATA), ' abcdefghijklmnopqrstuvwxyz' , ' ' ) AS "문자만제거"
     , TRANSLATE (LOWER(DATA), 'abcdefghijklmnopqrstuvwxyz'||DATA , 'abcdefghijklmnopqrstuvwxyz' ) AS "문자만남기기"
FROM (SELECT EMPNO||ENAME||HIREDATE AS DATA  
        FROM EMP )

 

 

DATA 숫자만제거 숫자만남기기 문자만제거 문자만남기기
7698BLAKE81/05/01 BLAKE// 7698810501 769881/05/01 blake
7782CLARK81/06/09 CLARK// 7782810609 778281/06/09 clark
7566JONES81/04/02 JONES// 7566810402 756681/04/02 jones
7902FORD81/12/03 FORD// 7902811203 790281/12/03 ford
7369SMITH80/12/17 SMITH// 7369801217 736980/12/17 smith
7499ALLEN81/02/20 ALLEN// 7499810220 749981/02/20 allen
7521WARD81/02/22 WARD// 7521810222 752181/02/22 ward
7654MARTIN81/09/28 MARTIN// 7654810928 765481/09/28 martin
7844TURNER81/09/08 TURNER// 7844810908 784481/09/08 turner
7900JAMES81/12/03 JAMES// 7900811203 790081/12/03 james
7934MILLER82/01/23 MILLER// 7934820123 793482/01/23 miller
7876ADAMS87/05/23 ADAMS// 7876870523 787687/05/23 adams
7788SCOTT87/04/19 SCOTT// 7788870419 778887/04/19 scott
1111YODA81/11/17 YODA// 1111811117 111181/11/17 yoda
7839KING81/11/17 KING// 7839811117 783981/11/17 king

 

TRANSLATE 만 이해하면 문자열 다루는 함수는 거의 다 이해한 것이나 다름이 없다.

 

 

 

 

TRANSLATE( 데이터, 검색문자 , 치환문자)

 

문제

SELECT TRANSLATE ('abcde', '1234567890', ' ')  FROM DUAL

정답은?

'abcde' 그대로 출력된다. '1234567890' 로 검색해서 일치하는 것이 없기 때문이다.

 

문제

SELECT TRANSLATE ('12345', '1234567890', '12345') A
     , TRANSLATE ('12345', '1234567890', '67890') B
  FROM dual

A,B 결과는?

여기서 중요한 것은 A도 똑같지만 특히 B가 왜 '67890'이라는 결과가 나왔는지다

 

'1234567890' 에서 '67890' 이 있으니까 '67890' 나왔다고 생각했다면 틀렸다.

SELECT TRANSLATE ('12345', '1234567890', '12345') A
     , TRANSLATE ('12345', '1234567890', '67890') B
     , TRANSLATE ('12345', '1234567890', '0000067890') C
  FROM dual

 C가 어떤 결과가 나올 것 같은가?

답은 '00000' 이다. 

즉, 앞서 A 도 '12345' 가 '12345' 가 그대로 출력된게 아니라 치환되어 '12345'가 된것으로 값이 잘 맞아 떨어져 그대로 출력하게 된 것 처럼 보인 것이다.

즉, A, B 다 치환된 결과이다.

 

 

'1234567890'  검색문자가 어떻게 치환되는지 알아보자

문제

SELECT TRANSLATE ('54321', '1234567890', '12345') A
     , TRANSLATE ('54321', '1234567890', '67890') B
     , TRANSLATE ('54321', '1234567890', '0000067890') C
  FROM dual

단순히 데이터를 '12345'에서 '54321' 로 변경했다. 결과가 어떻게 나올까?

아마도 B에서 복잡하게 느껴지는 사람이 많을 것 같다. 따라서 B를 기준으로 설명하겠다.

여기서 핵심은 검색문자와 치환문자 변경 규칙은 위치, 즉 인덱스에 정확히 대응된다는 것을 염두하자

 

1회차 TRANSLATE ('54321', '1234567890', '67890')   ===>  '04321'

데이터 첫번째 문자 '5' 를 검색문자에 같은 '5'가 존재한다. 치환문자에 같은 위치 '0' 으로 치환된다.

2회차 TRANSLATE ('04321', '1234567890', '67890')   ===>  '09321'

데이터 두번째 문자 '4' 를 검색문자에 같은 '4'가 존재한다. 치환문자에 같은 위치 '9' 으로 치환된다.

똑같이 5회차까지 진행되서 '09876' 이 나온 것이다. 

SELECT DATA
     , TRANSLATE (DATA, ' 1234567890', ' ') AS "숫자만제거"
     , TRANSLATE (DATA, '1234567890'||DATA, '1234567890') AS "숫자만남기기"
     , TRANSLATE (LOWER(DATA), ' abcdefghijklmnopqrstuvwxyz' , ' ' ) AS "문자만제거"
     , TRANSLATE (LOWER(DATA), 'abcdefghijklmnopqrstuvwxyz'||DATA , 'abcdefghijklmnopqrstuvwxyz' ) AS "문자만남기기"
FROM (SELECT EMPNO||ENAME||HIREDATE AS DATA  
        FROM EMP )

 

DATA 숫자만제거 숫자만남기기 문자만제거 문자만남기기
7698BLAKE81/05/01 BLAKE// 7698810501 769881/05/01 blake
7782CLARK81/06/09 CLARK// 7782810609 778281/06/09 clark
7566JONES81/04/02 JONES// 7566810402 756681/04/02 jones
7902FORD81/12/03 FORD// 7902811203 790281/12/03 ford
7369SMITH80/12/17 SMITH// 7369801217 736980/12/17 smith
7499ALLEN81/02/20 ALLEN// 7499810220 749981/02/20 allen
7521WARD81/02/22 WARD// 7521810222 752181/02/22 ward
7654MARTIN81/09/28 MARTIN// 7654810928 765481/09/28 martin
7844TURNER81/09/08 TURNER// 7844810908 784481/09/08 turner
7900JAMES81/12/03 JAMES// 7900811203 790081/12/03 james
7934MILLER82/01/23 MILLER// 7934820123 793482/01/23 miller
7876ADAMS87/05/23 ADAMS// 7876870523 787687/05/23 adams
7788SCOTT87/04/19 SCOTT// 7788870419 778887/04/19 scott
1111YODA81/11/17 YODA// 1111811117 111181/11/17 yoda
7839KING81/11/17 KING// 7839811117 783981/11/17 king

 

 

"숫자만제거"의 결과가 저렇게 왜 저렇게 나왔을까?

TRANSLATE (DATA, ' 1234567890', ' ')  핵심은 공백 활용과 치환할 문자가 없음을 이해하는 것이다.

검색문자 맨 앞에 ' ' 공백이 존재한다. 치환문자는 ' ' 공백만 존재한다. 

즉, 공백이 존재하면 공백으로 치환한다. 이후 검색문자 '1234567890'은 치환할 문자가 없으므로 null처리(제거)가 된다.

검색문자 이외 철자나, 특수문자는 그대로 남아 BLAKE// .... KING// 이런 결과가 나온 것이다.

 

"숫자만남기기"의 결과를 살펴보자

(DATA, '1234567890'||DATA, '1234567890')   핵심은 데이터 활용(||) 하는 것이다

원리는 이전 치환할 문자가 없다는 것을 이용한다.

검색문자에서 '1234567890'||DATA 중 '1234567890'는 치환문자 '1234567890' 대응되어 먼저 처리된다. 

"7698BLAKE81/05/01" 를 예를 들자면 치환문자  '1234567890' 0까지 처리된 직후 결과는 "숫자만제거" 결과인 "BLAKE//" 상태일 것이다. 이후 치환할 문자가 없으니 null처리 되어 숫자만 제외하고 다 null처리된 것이다.

 

문자 처리도 숫자처리와 원리는 완벽히 같다. 다만 대소문자 구분을 한다는 것을 알리기 위해 LOWER함수만 추가 썼을 뿐 모든 면에서 동일하다.

 

 

만약 당장 이해하기 어렵다면, 위 표를 보고 공식처럼 대입해서 사용하면 된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'개발 > 오라클 SQL' 카테고리의 다른 글

NULL을 다룰 때 주의할 점  (0) 2022.12.23
오라클 비밀번호 만료  (0) 2022.11.27
IN, NOT IN, EXISTS, NOT EXISTS  (0) 2022.11.10
마이바티스 null 체크  (0) 2022.09.28
정규식을 통한 Mybatis Sql Injection 처리  (0) 2022.06.29

+ Recent posts