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中的编码方式非常不同。小数需要更多空间。尝试SELECT CONVERT(VARBINARY(32), 1), CONVERT(VARBINARY(32), 1.0);
亚伦·伯特兰

4
亚伦是现场。您的大脑正在将二进制数据转换为整数数据,然后直接转换为数字,但是SQL Server不会从二进制->整数-> numeric(x,y)进行隐式转换。为了使SQL Server遵循您的思考过程,您必须执行以下操作:PRINT CONVERT(NUMERIC(38, 0), convert(int, 0x00000001), 0); PRINT CONVERT(NUMERIC(38, 0), convert(int, 0x00010001), 0);
Thomas Stringer 2014年

5
第一个字节是小数位(0x01 = 1),第二个字节是精度(0x00 = 0),最后一个字节是值(0x01 = 1)。不知道第三个字节和第四个字节是什么。标志在那里,但是不需要两个字节。当然,翻转那一点似乎并没有影响任何事情。
马丁·史密斯

1
谢谢@MartinSmith-您究竟是如何确定像这样使用前两个字节的?有记录吗?
马克斯·弗农

3
@AaronBertrand:您想做出一个答案吗?我们可以将其标记为“未答复”列表。
所有行业的乔恩2015年

Answers:


2

小数和整数在varbinary中的编码方式非常不同。小数需要更多空间。尝试:

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

至于您的最终目标,将整数存储为varbinary以节省空间,我认为您自己回答了这个问题-不值得。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.