금액 등의 화폐값을 표시할 때 사이베이스에서 부정확한 소수점 결과를 보여주는 사례가 종종 발생함.
float은 수치연산에 부적합하며 double precision을 쓰라는 사이베이스 엔지니어의 권고를 받아들여
double precision으로 처리하였으나 역시 연산에 부정확함.
이 부정확하다는 것은 SQL 클라이언트툴에서 보여지는 결과값이 3.938인 경우(그리드형태) 이를 텍스트형태로 변환해 보거나 그리드의 셀을 더블클릭했을 때 3.9383828381 과 같은 결과가 나와 화면상에 3.9383828381 이 그대로 출력되어버리는 문제였음.
ASIS시스템은 sybase ASE 12.0 이며 노츠로 개발된 화면이었고 문제가 발생한 적이 없었다 함. 그러나 차세대는 sybase ASE 15.5이며 전자정부프레임워크+웹스퀘어 기반의 화면이나 문제가 발생하므로 아래와 같은 형태로 사이베이스 엔지니어가 조치를 취해 줌.
select CASE WHEN amt=0 THEN '0'
/*제약사항
double 경우 48개의 유효 자리 숫자 가짐.
Decimal 경우 38개의 유효 자리 숫자 가짐.
* 알고리즘
-- left 0 padding remove
select substring(ColumnName, patindex('%[^0]%',ColumnName), char_length(ColumnName) )
-- 오른쪽 0 padding remove
reverse ( left 0 padding (reverse (columnName) )
-- pattern index의 문제점
0.00000... 일 경우 처리 에러발생 --> case 문에서 분기처리
*/
ELSE reverse(substring(reverse( convert(VARCHAR, convert(DECIMAL(30,8), amt)) ), patindex('%[^0]%',reverse(convert(VARCHAR, convert(DECIMAL(30,8), amt)))), char_length( convert(VARCHAR, convert(DECIMAL(30,8), amt)))))
END AS AMT_STRING
FROM <table_name>
'사이베이스(ASE)' 카테고리의 다른 글
사이베이스 날짜 표현 형식 (0) | 2013.07.02 |
---|---|
사이베이스 암호화 (0) | 2013.07.02 |
사이베이스의 날짜 표현 형식은 아래와 같다.
Style number | 설명 |
0 | Aug 27 2007 5:28PM |
1 | 08/27/07 |
2 | 07.08.27 |
3 | 27/08/07 |
4 | 27.08.07 |
5 | 27-08-07 |
6 | 27 Aug 07 |
7 | Aug 27, 07 |
8 | 17:23:35 |
9 | Aug 27 2007 5:28:08:563PM |
10 | 08-27-07 |
11 | 07/08/27 |
12 | 070827 |
13 | 07/27/08 |
14 | 08/07/27 |
15 | 27/07/08 |
16 | Aug 23 2007 17:28:08 |
18 | 15:17:08 |
19 | 5:11:39:086PM |
20 | 17:12:30:633 |
21 | 07/08/27 |
22 | 07/08/27 |
100 | Aug 27 2007 5:28PM |
101 | 08/27/2007 |
102 | 2007.08.07 |
103 | 27/08/2007 |
104 | 27.08.2007 |
105 | 27-08-2007 |
106 | 27 Aug 2007 |
107 | Aug 27, 2007 |
108 | 17:28:08 |
109 | Aug 27 2007 5:28:08:563PM |
110 | 08-27-2007 |
111 | 2007/08/27 |
112 | 20070827 |
113 | 2007/27/08 |
114 | 08/2007/27 |
115 | 27/2007/08 |
116 | Aug 23 2007 17:28:08 |
이게 무슨 말이냐....
여기에 dateadd 라는 함수를 사용하여 날짜형식의 다양한 컨트롤이 가능하다.
- SELECT dateadd(year,-1, getdate()) : 현재 년도에서 1년을 뺀 값
- SELECT dateadd(mm,-1, getdate()) : 현재 월에서 1월을 뺀 값
- SELECT dateadd(day,-1, getdate()) : 현재 일에서 1일을 뺀 값
이런 정보를 바탕으로 내가 하고자 하는 것은 아래와 같다.
masterid는 MA-2013-BOND-00012 의 형태이다.
masterid의 내부에 있는 년도를 취득하여 3년전부터 현재 년도 까지의 데이타를 추출하고자 한다.
SELECT bbbb + ' / ' + '본평가' + ' /' + convert(char, rcdate,112) , aaaa
FROM xxxx
WHERE aaaa=(SELECT aaaa FROM xxxx WHERE aaaa='xx-xxxx-xxxx-xxxxx')
AND cccc='01'
AND substring(xxxx,4,4) BETWEEN substring(convert(CHAR, dateadd(year,-3,getdate()), 112),1,4) AND substring(convert(CHAR, getdate(), 112),1,4)
ORDER BY xxxx
아래와 같은 결과가 출력된다.
BOND / 본평가 /20110927 MA-2011-BOND-00911
IR / 본평가 /19000101 MA-2011-IR-00077
[출처] Sybase 함수 모음|작성자 세상은나
'사이베이스(ASE)' 카테고리의 다른 글
사이베이스 float 타입의 문제점 (0) | 2013.07.02 |
---|---|
사이베이스 암호화 (0) | 2013.07.02 |
사이베이스(ASE)에서 inter_encrypt 함수를 통해서 암호화를 사용할 수 있다.
아래와 같은 조회조건은 암호화후의 값이 password와 동일한 것을 찾는 것이다.
select * from Manager where password = internal_encrypt("password")
마찬가지로 update문에서는 아래와 같이 사용할 수 있다. (ibatis 기준)
UPDATE EMP
SET password = internal_encrypt(#password:VARCHAR:NO_ENTRY#) ,
pw_change_date = #pw_change_date:VARCHAR:NO_ENTRY#,
updater = #user:VARCHAR:NO_ENTRY#
.
.
WHERE emp_no = #emp_no:VARCHAR:NO_ENTRY#
※ 참고로 VARCHAR:NO_ENTRY 는 NULL을 허용하겠다는 것이다. 물론 DDL에 해당 컬럼이 NULL이 허용되어 있어야 한다.
정수형의 경우에는 INTEGER:-999999 이다.
'사이베이스(ASE)' 카테고리의 다른 글
사이베이스 float 타입의 문제점 (0) | 2013.07.02 |
---|---|
사이베이스 날짜 표현 형식 (0) | 2013.07.02 |