⊙ 데이터타입: VARCHAR2 에 숫자를 넣으면? 숫자를 VARCHAR2 나 CHAR 에 넣어도 된다. 숫자를 사용하는 목적은 연산을 하기 위해서 인데, 문자형 데이터 타입을 사용하면 연산을 할 수 없다. 그런데, 사실은 문자 타입도 연산을 할 수 있다. 오라클이 내부적으로 문자 타입을 숫자 타입으로 변환하기 때문이다. 이 변환은 오라클 버전 별로 차이가 있으므로 항상 적용되는 것은 아니다. 사칙연산은 물론이고 SUM(), AVG(), 심지어 표준편차를 구하는 STDDEV() 함수도 문자가 적용된다. 확인해 보자. 테이블을 만들자. 값을 넣자. 소숫점도 넣어보자. INSERT INTO TTT VALUES ('5','7'); 더하기를 해보자. SELECT VC1, VC2, VC1+VC2 FROM TTT;
더하기가 잘 됐다. 표를 잘 보면 문자 정렬이 VC1, VC2 값은 왼쪽 정렬, 더한 값은 오를쪽 정렬로 되어 있다. 이는 문자를 숫자로 변환했음을 알 수 있다. 곱하기를 해보자. SELECT VC1, VC2, VC1*VC2 FROM TTT;
잘 된다. 나누기를 해보자. SELECT VC1, VC2, VC1/VC2 FROM TTT;
역시, 잘 된다. 빼기를 해보자. SELECT VC1, VC2, VC1-VC2 FROM TTT;
너무 잘된다. SUM() 은 될까? SELECT SUM(VC1), SUM(VC2) FROM TTT;
기대를 저버리지 않고 잘 됐다. 그럼, 평균은? SELECT AVG(VC1), AVG(VC2) FROM TTT;
두말하면 잔소리. 역시 잘된다. 이왕 하는 김에 표준편차도 해보자. SELECT STDDEV(VC1), STDDEV(VC2) FROM TTT;
하여간 잘된다. 최소값을 가져오는 MIN() 함수도 해볼까. 잘 될꺼야. 원래 값과 비교해 볼려고 UNION ALL 을 썼다. SELECT VC1, VC2 FROM TTT
어! 결과가 좀 이상하다. 제일 작은 숫자가 5 인데. 왜 10 이 제일 작은 숫자로 나왔지? 왜 이렇게 나왔지? 앞에 함수들은 잘 됐는데... 혹시... 버그가 있는게 아닐까?..... 이왕 테슽 해보는거 최대값을 가져오는 MAX() 도 해보자. SELECT VC1, VC2 FROM TTT
헉! 이것도 이상하네.. 15, 25 가 나와야 하는데 8.5, 7 이 나왔네... 더구나 7은 가장 작은 수인데.... 정말 버그가 있는걸까?... 그런데, 아주 많은 사람들이 쓰고 있는 오라클인데 설마 이런 버그가 있을리가... 버그가 있었어도 벌써 고쳤겠지... 지금까지 그대로 있을려구... 에구.. 잘 모르겠다. 커피 한잔 하며 좀 쉬어야 겠다. 잠깐, 앞에 함수들과 뭔가 다른게 있나?..... 잘 생각해 보자. 앞에 쓴 SUM(), AVG(), STDDEV() 함수는 모두 숫자를 계산하는 함수들인데. MIN() 도 마찬가지 아닌가? 작다, 크다... 아!.... 문자도 해당되는거 같은데.. A 와 B 를 비교할 수 있나?. A = B, A > B, A < B 이런 것들... 해보면 되지.. SELECT 'A' = 'B' FROM DUAL; ORA-00923: FROM 키워드가 필요한 위치에 없습니다. 앵!.. 왠 에러가?..... 이렇게는 할 수 없나보네... 그럼, WHERE 절에 넣어볼까... SELECT * FROM DUAL 비교 테스트 해보는 것도 쉽지 않군... 어떻게 비교하지?.... 아! CASE 를 써 볼까... 우선 'A' 하고 'A' 를 비교해서 같으면 'TRUE' 를, 다르면 'FALSE' 를 보여주게 하자. SELECT CASE WHEN 'A' = 'A' THEN 'TRUE' ELSE 'FALSE' END FROM DUAL;
오호! 잘된다. 그럼, 'A' = 'B' 를 비교해보자. SELECT CASE WHEN 'A' = 'B' THEN 'TRUE' ELSE 'FALSE' END FROM DUAL;
맞네.. 'A' 와 'B' 는 다르지. 그럼, 'A' > 'B', 'A' < 'B' 도 비교해보자. SELECT CASE WHEN 'A' > 'B' THEN 'TRUE' ELSE 'FALSE' END FROM DUAL;
문자도 비교가 되는군. 그럼, MIN(), MAX() 함수는 문자도 비교해서 보여주는 구나. 여기서 VC1, VC2 모두 문자 데이터 타입이니, 문자로 비교해서 보여주면... 결과를 다시 살펴보자.
문자는 맨 앞자부터 비교하니 VC1 에서는 1로 시작하는게 10, 15 이고 이중 2번째 문자를 비교하니 10 이 가장 작군. VC2 의 11.3 도 마찬가지네. 그럼, 여기서 MIN(), MAX() 함수는 원래 VC1, VC2 의 데이터 타입이 문자이니 그대로 문자의 크고, 작음을 비교했구나.... 원래 문제로 돌아가 보자. 문자 데이터 타입에 숫자를 넣을 수 있다고 해서 그렇게 하는게 맞는가? 오라클이 내부적으로 문자를 숫자로 변환하므로 내부 연산이 필요해서 적지만 성능에 악 영향을 미친다. 그리고 더 큰 문제는 앞의 테스트에서 처럼 MIN(), MAX() 같이 예상치 못한 결과가 나올 수 있다. 그러므로 문자는 문자 데이터 타입에, 숫자는 숫자 데이터 타입에 넣어야 한다. |