int _tmain(int argc, _TCHAR* argv[])
{
int nValue = 65535;
int nLowValue = LOBYTE( nValue );
int nHighValue = HIBYTE( nValue );
cout << "nLowValue : " << nLowValue << endl;
cout << "nHighValue : " << nHighValue << endl;
return 0;
}
{
int nValue = 65535;
int nLowValue = LOBYTE( nValue );
int nHighValue = HIBYTE( nValue );
cout << "nLowValue : " << nLowValue << endl;
cout << "nHighValue : " << nHighValue << endl;
return 0;
}
C++ 코딩에서는 위와 같이 매크로를 이용해서 BYTE 단위로 쪼개기도 하고,
int _tmain(int argc, _TCHAR* argv[])
{
int nValue = 65535;
int nLowValue = nValue & 0xFF;
int nHighValue = (nValue >> 8) & 0xFF;
cout << "nLowValue : " << nLowValue << endl;
cout << "nHighValue : " << nHighValue << endl;
return 0;
}
{
int nValue = 65535;
int nLowValue = nValue & 0xFF;
int nHighValue = (nValue >> 8) & 0xFF;
cout << "nLowValue : " << nLowValue << endl;
cout << "nHighValue : " << nHighValue << endl;
return 0;
}
위와 같이 쉬프트 연산자와 & | 연산자를 이용하기도 하였습니다.
그러나 DB의 select 문에서는 위와 같은 방식을 사용할 수 없습니다.
SELECT (256 * 256)
위의 결과는 65535가 정상적으로 출력됩니다. 그럼 문제가 되는 구문을 살펴 보겠습니다.
SELECT (256 * 256 * 256 * 256)
이 구문은 논리적으로 오류가 없어 보입니다. 적어도 C++ 관점에서 본다면 그렇지요.
하지만, 문제점이 있습니다. DB는 기본적으로 select에 대한 계산식은 명시적으로 지정하지 않으면 int 연산으로 casting 하게 됩니다.
따라서 이와 같은 메시지가 나오게 되었습니다.
서버: 메시지 8115, 수준 16, 상태 2, 줄 1
expression을(를) 데이터 형식 int(으)로 변환하는 중 산술 오버플로 오류가 발생했습니다.
expression을(를) 데이터 형식 int(으)로 변환하는 중 산술 오버플로 오류가 발생했습니다.
그렇다면 어떻게 해결하면 될까요? 답은 간단합니다.
SELECT cast(256 AS bigint) * cast(256 AS bigint) * cast(256 AS bigint) * cast(256 AS bigint)
오버플로우가 발생하지 않도록 더 큰 자료형인 bigint로 캐스팅해서 연산해주면 됩니다.
저런 문제점이 발생한 배경은 bigint 자료형을 HILONG, LOLONG으로 나누고 싶었는데, 256을 4번 곱한 값으로 나누기 연산을 수행했을때, 위와 같은 문제점이 발생하였습니다.
이 문제에 대한 해결책을 알려주신 최선호(약올라)님에게 감사의 말씀을 드립니다.
-- 4번 곱하기가 눈에 거슬리시는 분들을 위한 팁
SELECT power( cast(256 AS bigint), 4)
덧글을 달아 주세요