select DATALENGTH(convert(Decimal(4,0),256)) result result ----------- 5 (1 row(s) affected)
但是,当我转换为二进制(5)然后再回到十进制(4,0)时,它会截断数据.
DECLARE @myval decimal (4,0); SET @myval = 257; SELECT CONVERT(decimal(4,CONVERT(varbinary(5),@myval)) result result --------------------------------------- 1 (1 row(s) affected)
数字的最后一个字节被切断.但是,如果我转换为二进制(6)或更多…我得到正确的结果:
DECLARE @myval decimal (4,CONVERT(binary(6),@myval)) result result --------------------------------------- 257 (1 row(s) affected)
怎么了?如果我需要存储十进制值的二进制表示,我怎么知道需要多少字节?具体来说,确定将十进制(p,s)转换为二进制(x)所需的最小字节数x的通用公式是什么?
我需要将一些二进制数据封送到服务代理消息中,因此我需要将各种类型的数据转换为二进制字符串.是否有更健壮的方法来存储二进制值,而不是使用强制转换?
解决方法
DATALENGTH is especially useful with varchar,varbinary,text,image,
nvarchar,and ntext data types because these data types can store
variable-length data.
十进制的最小长度为5个字节,最大为17个字节.十进制(p,s)不是可变长度数据.它具有精确的固定长度.例如,如果数字的长度是1到9的数字,那么DATALENGTH将始终返回5
select DATALENGTH(convert(Decimal(38,1)) -- result 5 select DATALENGTH(convert(Decimal(38,1234567890)) -- result 5
如果数字长度为10到19,则DATALENGTH将始终返回9
select DATALENGTH(convert(Decimal(38,12345678901)) -- result 9 select DATALENGTH(convert(Decimal(38,111111111111111)) -- result 9
所以,DATALENGTH的结果将取决于数字的长度,但它不是真正的长度.
当您将十进制(4,0)转换为二进制(5)时,您将获得0x04 00 00 01 00
在这种情况下,只剩下最后一个字节用于您的号码.您可以在1个字节中存储的最大数量是255(HEX中的255等于FF)
这样一切正常:
DECLARE @myval decimal (4,0); SET @myval = 255; SELECT CONVERT(decimal(4,CONVERT(binary(5),@myval)) result,@myval) result HEX --------------------------------------- ------------ 255 0x04000001FF
现在,尝试256号而不是255. HEX中的256等于100,我们不能在1字节中存储100(HEX应该是0x04 00 00 01 00 1但是没有1的空间)
DECLARE @myval decimal (4,0); SET @myval = 256; SELECT CONVERT(decimal(4,@myval) HEX result HEX --------------------------------------- ------------ 0 0x0400000100
如果要存储0到9999之间的数字,则至少需要6个字节.看257(十六进制等于101)
DECLARE @myval decimal (4,@myval) HEX result HEX --------------------------------------- -------------- 256 0x040000010101
这里我们有6个字节0x04 00 00 01 01 01和01 01
然后9999(HEX等于270F)
DECLARE @myval decimal (4,0); SET @myval = 9999; SELECT CONVERT(decimal(4,@myval) HEX result HEX --------------------------------------- -------------- 9999 0x040000010F27
最后6个字节0x04 00 00 01 0F 27和27 0F. (从右到左阅读)