CONVERT ()에서이 문제의 원인은 무엇입니까?


12

다음 두 문장을 고려하십시오.

PRINT CONVERT(NUMERIC(38, 0), 0x0100000001, 0);
PRINT CONVERT(NUMERIC(38, 0), 0x0100010001, 0);

두 문장 모두 리턴 -1; 두 번째 이진 값이 첫 번째 값보다 65,536이 높으므로 정확하지 않습니까?

확실히 이것은 자동 자르기로 인한 것일 수 없습니까?

다음 문장을 실행하면 :

PRINT CONVERT(NUMERIC(38, 0),   0x00000001, 0);
PRINT CONVERT(NUMERIC(38, 0),   0x00010001, 0);

다음과 같은 오류가 나타납니다.

Msg 8114, Level 16, State 5, Line 1
Error converting data type varbinary to numeric.

여기서 무슨 일이 일어나고 있는지 어떻게 진단 할 수 있습니까?

SQL Server 2012, v11.0.5058에서 이것을 실행하고 있습니다. 결과는 SQL Server 2008 R2 SP2, SQL Server 2005 및 SQL Server 2000에서 동일합니다.


4
십진수와 정수는 varbinary에서 매우 다르게 인코딩됩니다. 소수는 더 많은 공간이 필요합니다. TrySELECT CONVERT(VARBINARY(32), 1), CONVERT(VARBINARY(32), 1.0);
Aaron Bertrand

4
아론이 현장에 있습니다. 당신의 두뇌는 이진 데이터를 정수 데이터로 변환 한 다음 숫자로 바로 변환하지만 SQL Server는 이진-> 정수-> 숫자 (x, y)에서 암시 적 변환을 수행하지 않습니다. SQL Server가 사고 과정을 따르려면 다음과 같은 작업을 수행해야합니다 PRINT CONVERT(NUMERIC(38, 0), convert(int, 0x00000001), 0); PRINT CONVERT(NUMERIC(38, 0), convert(int, 0x00010001), 0);.
Thomas Stringer

5
첫 번째 바이트는 스케일 (0x01 = 1)이고 두 번째 바이트는 정밀도 (0x00 = 0)이며 마지막 바이트는 값 (0x01 = 1)입니다. 바이트 3과 4가 어떤 바이트인지 확실하지 않습니다. 부호가 있지만 2 바이트는 필요하지 않습니다. 확실히 그 비트를 뒤집는 것은 아무것도 영향을 미치지 않은 것 같습니다.
Martin Smith

1
감사합니다, @MartinSmith-지구상에서 처음 두 바이트가 어떻게 사용되는지 결정 했습니까? 문서화되어 있습니까?
Max Vernon

3
@AaronBertrand : 그 대답을 하시겠습니까? "답변하지 않은"목록에서이를 표시 할 수 있습니다.
모든 거래의 존

답변:


2

십진수와 정수는 varbinary에서 매우 다르게 인코딩됩니다. 소수는 더 많은 공간이 필요합니다. 시험:

SELECT CONVERT(VARBINARY(32), 1), CONVERT(VARBINARY(32), 1.0);

공간을 절약하기 위해 정수를 varbinary로 저장하는 궁극적 인 목표는 그 질문에 스스로 대답했다고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.