TSql中有binary 和 varbinary 这两种数据类型,用于存储二进制数据。
1, 语法,
binary [ ( n ) ]
长度为 n 字节的固定长度二进制数据,其中 n 是从 1 到 8,000 的值。存储大小为 n 字节。
varbinary [ ( n | max) ]
可变长度二进制数据。 n 的取值范围为 1 至 8,000。 max 指示最大存储大小是 2^31-1 个字节。 存储大小为所输入数据的实际长度 + 2 个字节。 所输入数据的长度可以是 0 字节。
如果没有在数据定义或变量声明语句中指定 n,则默认长度为 1。 如果没有使用 CAST 函数指定 n,则默认长度为 30
MSDN上说,binary 和 varbinary 存储的单位并不是bit,而是 byte,示例如下
declare @varBi binary(1) set @varBi=1 print @varBi
输出结果是:0x01
输出的结果是以16进制编码显示,共8bit。
2,类型转换
2.1 int类型隐式转换成binary类型,int类型可以隐式转换成binary类型,binary可以通过 cast,convert 转换成int类型。
declare @varBi binary(1) set @varBi=1 print @varBi print cast(@varbi as int)
可以把binary转换成int类型,输出的结果是1
2.2 char类型不能隐式转换成binary类型,需要显式转换,通过 cast 和 convert 显式转换成 binary类型。
declare @varBi binary(8) set @varBi=cast(‘1‘ as binary(8)) print @varBi print cast(@varbi as varchar) ---- 0x3100000000000000 ---- 1
输出结果是字符 “1”,而不是数字1,这说明binary是逐个字节转换的。0X31是16进制,代表的10进制数值是49,和“1”的ASCII值是相同的。
在0X31 有7个byte,都是使用0x00来填充。
2.3 从字符数据类型转换成binary或varbinary类型时,将在右侧发生截断或填充,填充将通过使用十六进制的零来完成。
当数据从字符串数据类型(char、varchar、nchar、nvarchar、binary、varbinary、text、ntext 或 image)转换为不同长度的 binary 或 varbinary 数据类型时,SQL Server 将在数据的右侧填充或截断数据。
从字符串的左边逐字节转换,如果字符串的长度大于binary的长度,则右边截断;如果字符串的长度小于binary的长度,则右边填充0x00;
declare @varBi binary(2) set @varBi=cast(‘123‘ as binary(8)) print @varBi print cast(@varbi as varchar) ---- 0x3132 ---- 12
declare @varBi binary(8) set @varBi=cast(‘123‘ as binary(8)) print @varBi print cast(@varbi as varchar) ---- 0x3132330000000000 ---- 123
2.4 从int数据类型转换为 binary 或 varbinary 时,将在数据的左侧填充或截断数据,填充将通过使用十六进制的零来完成。
可以将 int、smallint 和 tinyint 转换为 binary 或 varbinary,但是如果将 binary 转换回整数值,则在发生了截断的情况下此值将不同于原始整数值。
declare @biToInt binary(1) set @biToInt=300 print @biToInt print cast(@biToInt as int) -- 0x2C -- 44
由于binary(1)是8位bit,最多存储255,发生上溢,左侧发生截断,舍弃左边高位 数值 256,保留低位数值44
declare @biToInt binary(3) set @biToInt= 12 print @biToInt print cast(@biToInt as int) --0x00000C --12
如果没有溢出,那么不管int类型数值有多大,都能生成相同的值,如果binary长度较长,那么左侧填充为0x00。
2.5 从其他数据类型(除了字符数据类型之外的)转换为 binary 或 varbinary 时,将在数据的左侧填充或截断数据。 填充将通过使用十六进制的零来完成。
如果 binary 数据是最容易来回移动的数据,则将数据转换为 binary 和 varbinary 数据类型很有用。 将任一类型的任一值转换为足够大的二进制值,然后转换回原类型时,如果两次转换都是在相同的 SQL Server 版本上进行的,将始终生成相同的值。 值的二进制表示形式在不同 SQL Server 版本之间可能会有所不同。
3 binary 类型的数据如何比较大小?
SQL进行数值比较之前,首先进行数据类型的匹配,将两个操作数的数据类型提升为相同数据类型。
binary的长度是十分重要的,在两个binary类型的变量之间进行比较时,会将位数低的数据类型提升,保持两个操作数的位数相同。
提升的位数使用0x00填充,并且是在右侧填充,这将增大binary的数值。
declare @biA binary(1) declare @biB binary(2) set @biA=1 set @biB=2 print @bia print @bib if @biA >= @biB begin print ‘>=‘ end else print ‘<‘ -- 0x01 -- 0x0002 -- >=
在比较时,@biA在右侧填充一个byte,变成0x0100,数值是256,所以比较的结果是 >=;如果set @biB=257,那么输出的结果将是<
declare @biA varbinary(1) declare @biB varbinary(2) set @biA=1 set @biB=257 print @bia print @bib if @biA >= @biB begin print ‘>=‘ end else print ‘<‘ -- 0x01 -- 0x0101 -- <
4,赋值,binary的存储单位是byte,可以直接使用16进制数值为binary变量赋值
declare @biA binary(1) set @biA= 0x01 print @biA