LENGTH/LENGTHB,SUBSTR/SUBSTRB,INSTR/INSTRB
조건.
우리가 이미 만들어 놓은 테이블 중 T_MANAGER라는 테이블이 있다.
UTILITY MAIN_EMP SUB1_EMP SUB2_EMP
-------------------- --------- --------- ---------
소방시설 7366
전기시설 7499 7521
전산장비 7782
저장시설 7698
수송설비 8854
냉방시설 7566 7654 7844
수도시설 7876 7900 7844
문제.
이번 주제에서 하고자 하는 일은 ORACLE 함수중 STRING과 관련되어
그 길이를 이용하는 함수중 LENGTH,SUBSTR,INSTR 함수이다.
그 차이점에 대해서 알아보자.
SELECT INSTR(UTILITY,'시') I1,INSTRB(UTILITY,'시') I2,
INSTR(MAIN_EMP,4) I3,INSTRB(MAIN_EMP,4) I3,
SUBSTR(UTILITY,2,2) S1,SUBSTRB(UTILITY,2,2) S2,
SUBSTRB(UTILITY,3,2) S3,SUBSTRB(UTILITY,3,1) S4,
SUBSTR(MAIN_EMP,2,1) S5,SUBSTRB(MAIN_EMP,2,1) S6,
LENGTH(UTILITY) L1,LENGTHB(UTILITY) L2,
LENGTH(MAIN_EMP) L3,LENGTHB(MAIN_EMP) L4
FROM T_MANAGER;
생각.
SELECT USERENV('LANGUAGE') FROM DUAL;
위의 문장을 실행시키면
----------------------------------------------------
KOREAN_KOREA.KO16KSC5601
처럼 INIT.ORA의 LANGUAGE PARAMETER 로 지정되어 있는 언어가
리턴된다.
LANGUAGE PARAMETER가 영문일 경우는 SUBSTR,LENGTH,INSTR 이나
그 뒤에 B 가 붙으나 똑같은 값을 RETURN하고 DATA가 한글일 경우는
위의 함수들중 SUBSTR/SUBSTRB 는 깨짐현상이 일어나는 것으로
알고 있다.
어쨌든 LANGUAGE PARAMETER 가 한글일 경우 그차이는 분명히 있다.
위의 8가지 경우에대한 결과 값을 생각해보자.
INSTR,SUBSTR,LENGTH 는 DATA가 한글이든 영문이든 문자수를 이용해
처리한다.
하지만 INSTRB,SUBSTRB,LENGTHB는 한글1자는 2바이트,영문1자는
1바이트로 처리한다.
문제의 문장을 수행한 결과가 어떻게 나올지 상상해 보자.
해법.
I1 I2 I3 I3 S1 S2 S3 S4 S5 S6 L1 L2 L3 L4
--- --- --- --- ---- -- -- -- -- -- ---- ---- ---- ----
3 5 0 0 방시 방 5 5 4 8 4 4
3 5 2 2 기시 기 4 4 4 8 4 4
3 5 0 0 도시 도 8 8 4 8 4 4
0 0 0 0 산장 산 7 7 4 8 4 4
3 5 0 0 장시 장 6 6 4 8 4 4
3 5 0 0 방시 방 5 5 4 8 4 4
0 0 4 4 송설 송 8 8 4 8 4 4
3 5 0 0 명시 명 9 9 4 8 4 4
실행 결과다.
첫번째 RECORD를 하나씩 분석해 보자.
INSTR(UTILITY,'시') 는 '소방시설' 에서 '시'가 나타나는 첫번째 자리가
얼마인가에 대한 답을 요구하고 있다.
결과는 3 이다. 한글 한자를 1개의 문자로 처리했다는 얘기다.
반면 INSTRB(UTILITY,'시') 는 어떤가?. 답이 5를 리턴했다.
한글 1글자를 2개의 바이트로 인식했다는 뜻이다.
숫자를 이용해 비슷한 요구를 한 I3,I4는 두번째 ROW에서 같은 결과인
4를 리턴했다. 영문도 마찬가지다.
영문/숫자 에서는 INSTR이나 INSTRB 가 같은 결과를 리턴한다는 것을
알 수 있다.
LENGTH 와 LENGTHB,SUBSTR 과 SUBSTRB 도 같은 방식이다.
S2 컬럼 즉 SUBSTRB(UTILITY,2,2)을 보자.
'소방시설' 에서 바이트 단위로 2번째에서 2자를 요구했다.
결과는 어떤가?
NULL이 나왔다. 2바이트가 1개의 글자인 한글에서
2번째 바이트 부터의 값을 요구했기 때문에 답을 내줄 수 없었던
것이다.
하지만 S3 에서 SUBSTRB(UTILITY,3,2) 와 같이 3번째부터 2개의
문자를 요구하자
'방' 이라는 하나의 글자를 RETURN 했다.
당연한 결과일 것이다.
S4는 어떤가?.
한글을 3번째부터 1개의 바이트만 요구하고 있다.
결과는 물론 NULL이다.
2바이트가 한개의 문자인 한글을 바이트 단위로 끊어서 결과를
내 줄수 없다는 것을 알 수 있다.
한글과 영문에 있어서의 LENGTH와 LENGTHB는 더 이상
설명하지 않아도 같은 원칙이 적용된다.
뒷풀이.
아주 사소한 문제 같지만 자주 실수를 하는 부분이며,
애초에 SUBSTRB,LENGTHB,INSTRB 에 대해서 모르고 있는 경우도
허다하다.
그러니 둘의 차이에 대해서 모르는 것은 말할 나위도 없을 것이다.
알아두면 손해볼 것은 없을 것 같은데...
반면
SELECT USERENV('LANGUAGE') FROM DUAL;
을 실행 했을때
AMERICAN_AMERICA.US7ASCII
처럼 영문 PARAMETER로 지정된경우를 보자.
SELECT INSTR(UTILITY,'시') I1,INSTRB(UTILITY,'시') I2,
SUBSTR(UTILITY,2,2) S1,SUBSTRB(UTILITY,2,2) S2,
LENGTH(UTILITY) L1,LENGTHB(UTILITY) L2
FROM T_MANAGER
를 실행하면 아래의 결과가 나온다.
I1 I2 S1 S2 L1 L2
--------- --------- -- -- --------- ---------
5 5 拈 拈 8 8
5 5 ??nbsp; 8 8
0 0 ??nbsp; 8 8
5 5 ??nbsp; 8 8
0 0 梔 梔 8 8
5 5 첫 첫 8 8
5 5 層 層 8 8
조건.
우리가 이미 만들어 놓은 테이블 중 T_MANAGER라는 테이블이 있다.
UTILITY MAIN_EMP SUB1_EMP SUB2_EMP
-------------------- --------- --------- ---------
소방시설 7366
전기시설 7499 7521
전산장비 7782
저장시설 7698
수송설비 8854
냉방시설 7566 7654 7844
수도시설 7876 7900 7844
문제.
이번 주제에서 하고자 하는 일은 ORACLE 함수중 STRING과 관련되어
그 길이를 이용하는 함수중 LENGTH,SUBSTR,INSTR 함수이다.
그 차이점에 대해서 알아보자.
SELECT INSTR(UTILITY,'시') I1,INSTRB(UTILITY,'시') I2,
INSTR(MAIN_EMP,4) I3,INSTRB(MAIN_EMP,4) I3,
SUBSTR(UTILITY,2,2) S1,SUBSTRB(UTILITY,2,2) S2,
SUBSTRB(UTILITY,3,2) S3,SUBSTRB(UTILITY,3,1) S4,
SUBSTR(MAIN_EMP,2,1) S5,SUBSTRB(MAIN_EMP,2,1) S6,
LENGTH(UTILITY) L1,LENGTHB(UTILITY) L2,
LENGTH(MAIN_EMP) L3,LENGTHB(MAIN_EMP) L4
FROM T_MANAGER;
생각.
SELECT USERENV('LANGUAGE') FROM DUAL;
위의 문장을 실행시키면
----------------------------------------------------
KOREAN_KOREA.KO16KSC5601
처럼 INIT.ORA의 LANGUAGE PARAMETER 로 지정되어 있는 언어가
리턴된다.
LANGUAGE PARAMETER가 영문일 경우는 SUBSTR,LENGTH,INSTR 이나
그 뒤에 B 가 붙으나 똑같은 값을 RETURN하고 DATA가 한글일 경우는
위의 함수들중 SUBSTR/SUBSTRB 는 깨짐현상이 일어나는 것으로
알고 있다.
어쨌든 LANGUAGE PARAMETER 가 한글일 경우 그차이는 분명히 있다.
위의 8가지 경우에대한 결과 값을 생각해보자.
INSTR,SUBSTR,LENGTH 는 DATA가 한글이든 영문이든 문자수를 이용해
처리한다.
하지만 INSTRB,SUBSTRB,LENGTHB는 한글1자는 2바이트,영문1자는
1바이트로 처리한다.
문제의 문장을 수행한 결과가 어떻게 나올지 상상해 보자.
해법.
I1 I2 I3 I3 S1 S2 S3 S4 S5 S6 L1 L2 L3 L4
--- --- --- --- ---- -- -- -- -- -- ---- ---- ---- ----
3 5 0 0 방시 방 5 5 4 8 4 4
3 5 2 2 기시 기 4 4 4 8 4 4
3 5 0 0 도시 도 8 8 4 8 4 4
0 0 0 0 산장 산 7 7 4 8 4 4
3 5 0 0 장시 장 6 6 4 8 4 4
3 5 0 0 방시 방 5 5 4 8 4 4
0 0 4 4 송설 송 8 8 4 8 4 4
3 5 0 0 명시 명 9 9 4 8 4 4
실행 결과다.
첫번째 RECORD를 하나씩 분석해 보자.
INSTR(UTILITY,'시') 는 '소방시설' 에서 '시'가 나타나는 첫번째 자리가
얼마인가에 대한 답을 요구하고 있다.
결과는 3 이다. 한글 한자를 1개의 문자로 처리했다는 얘기다.
반면 INSTRB(UTILITY,'시') 는 어떤가?. 답이 5를 리턴했다.
한글 1글자를 2개의 바이트로 인식했다는 뜻이다.
숫자를 이용해 비슷한 요구를 한 I3,I4는 두번째 ROW에서 같은 결과인
4를 리턴했다. 영문도 마찬가지다.
영문/숫자 에서는 INSTR이나 INSTRB 가 같은 결과를 리턴한다는 것을
알 수 있다.
LENGTH 와 LENGTHB,SUBSTR 과 SUBSTRB 도 같은 방식이다.
S2 컬럼 즉 SUBSTRB(UTILITY,2,2)을 보자.
'소방시설' 에서 바이트 단위로 2번째에서 2자를 요구했다.
결과는 어떤가?
NULL이 나왔다. 2바이트가 1개의 글자인 한글에서
2번째 바이트 부터의 값을 요구했기 때문에 답을 내줄 수 없었던
것이다.
하지만 S3 에서 SUBSTRB(UTILITY,3,2) 와 같이 3번째부터 2개의
문자를 요구하자
'방' 이라는 하나의 글자를 RETURN 했다.
당연한 결과일 것이다.
S4는 어떤가?.
한글을 3번째부터 1개의 바이트만 요구하고 있다.
결과는 물론 NULL이다.
2바이트가 한개의 문자인 한글을 바이트 단위로 끊어서 결과를
내 줄수 없다는 것을 알 수 있다.
한글과 영문에 있어서의 LENGTH와 LENGTHB는 더 이상
설명하지 않아도 같은 원칙이 적용된다.
뒷풀이.
아주 사소한 문제 같지만 자주 실수를 하는 부분이며,
애초에 SUBSTRB,LENGTHB,INSTRB 에 대해서 모르고 있는 경우도
허다하다.
그러니 둘의 차이에 대해서 모르는 것은 말할 나위도 없을 것이다.
알아두면 손해볼 것은 없을 것 같은데...
반면
SELECT USERENV('LANGUAGE') FROM DUAL;
을 실행 했을때
AMERICAN_AMERICA.US7ASCII
처럼 영문 PARAMETER로 지정된경우를 보자.
SELECT INSTR(UTILITY,'시') I1,INSTRB(UTILITY,'시') I2,
SUBSTR(UTILITY,2,2) S1,SUBSTRB(UTILITY,2,2) S2,
LENGTH(UTILITY) L1,LENGTHB(UTILITY) L2
FROM T_MANAGER
를 실행하면 아래의 결과가 나온다.
I1 I2 S1 S2 L1 L2
--------- --------- -- -- --------- ---------
5 5 拈 拈 8 8
5 5 ??nbsp; 8 8
0 0 ??nbsp; 8 8
5 5 ??nbsp; 8 8
0 0 梔 梔 8 8
5 5 첫 첫 8 8
5 5 層 層 8 8
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
54 | 소계/합계 함께 보기 | 운영자 | 2002.09.18 | 3134 |
53 | 석차구하기 | 운영자 | 2002.09.18 | 2960 |
52 | COLUMN을 ROW로 | 운영자 | 2002.09.18 | 6135 |
51 | 최대값과 최소값을 뺀 평균 | 운영자 | 2002.09.18 | 4177 |
50 | 누계를 구하는 또한가지 방법 | 운영자 | 2002.09.18 | 3209 |
49 | 그룹 단위별 일련번호 붙이기 | 운영자 | 2002.09.18 | 5754 |
48 | 부등호 조인 | 운영자 | 2002.09.18 | 56706 |
47 | 행렬(matrix)계산을위한 준비 | 운영자 | 2002.09.18 | 3062 |
46 | 최대값과 해당해의 다른값 가져오기 | 운영자 | 2002.09.18 | 3222 |
45 | DATA 병합 | 운영자 | 2002.09.18 | 2578 |
44 | 다수 NULL 허용 COLUMN의 명칭을 가져올때 | 운영자 | 2002.09.18 | 3732 |
43 | 수식이용 | 운영자 | 2002.09.18 | 2738 |
42 | JOIN과 SUBQUERY가 동일한 예제 | 운영자 | 2002.09.18 | 2950 |
41 | NULL과 0 의 AVG 차이 비교 | 운영자 | 2002.09.18 | 2875 |
40 | 고정된 Row 수 유지 | 운영자 | 2002.09.18 | 4229 |
39 | 두개 RECORD를 한행에 DISPLAY 시키기 | 운영자 | 2002.09.18 | 3162 |
» | LENGTH/LENGTHB,SUBSTR/SUBSTRB,INSTR/INSTRB | 운영자 | 2002.09.18 | 4292 |
37 | 한줄에 2 ROW 보여주기 변형II | 운영자 | 2002.09.18 | 3109 |
36 | 상호간 OUTER 조인의 해결방안 | 운영자 | 2002.09.18 | 2941 |
35 | 선택적조인 | 운영자 | 2002.09.18 | 2961 |