根据最近的问题.
有人能指出我对以下内容的解释吗?
如果我将binary(4)常量转换0x80000000为int,取得结果值并将其转换为bit类型,结果为1.
select cast(0x80000000 as int) --> -2147483648
select cast(-2147483648 as bit) --> 1
Run Code Online (Sandbox Code Playgroud)
但是如果我0x80000000直接转换为位类型,结果为0.
select cast(0x80000000 as bit) --> 0
Run Code Online (Sandbox Code Playgroud)
我希望在这种情况下得到1,认为可能这个表达相当于
select cast(cast(0x80000000 as binary(1)) as bit)
Run Code Online (Sandbox Code Playgroud)
但这种情况并非如此.相反,似乎采用二进制常量的最高字节并将其转换为位.所以,有效的是它
select cast(cast(right(0x80000000, 1) as binary(1)) as bit)
Run Code Online (Sandbox Code Playgroud)
我很清楚第一binary -> int -> bit部分.我不清楚的是第二binary -> bit部分.我无法在文档中找到此行为,仅在此处
转换为位会将任何非零值提升为1.
说明.
binary不是数字,而是一串字节.当您binary转换为其他类型时,将执行转换.当binary比目标数据类型长时,它将从左侧截断.当它比目标短时,用左边的零填充.例外情况是当转换为另一个字符串类型(例如varchar或另一个binary)时 - 从右边填充和截断,这可能有点令人困惑:)
那么这里发生了什么?
select cast(cast(0x0F as binary(1)) as bit) -- 1 - 0x0F is nonzero
select cast(cast(0x01 as binary(1)) as bit) -- 1 - 0x01 is nonzero
select cast(cast(0x01 as binary(2)) as bit) -- 0 - truncated to 0x00, which is zero
select cast(cast(0x0100 as binary(2)) as bit) -- 0 - truncated to 0x00
select cast(cast(0x0001 as binary(2)) as bit) -- 1 - truncated to 0x01, nonzero
Run Code Online (Sandbox Code Playgroud)
正如文件所说:
当数据从字符串数据类型(char,varchar,nchar,nvarchar,binary,varbinary,text,ntext或image)转换为不等长的二进制或varbinary数据类型时,SQL Server将填充或截断右侧的数据.当其他数据类型转换为二进制或varbinary时,数据在左侧填充或截断.通过使用十六进制零来实现填充.
这是你可以使用的东西,因为:
select cast(0x0100 as binary(1)) -- 0x01
Run Code Online (Sandbox Code Playgroud)
因此,如果整个值需要非零,则基本上需要转换为整数数据类型(如果可能).如果你想要最右边的字节,请使用cast as bit,如果你想要最左边的字节,请使用cast as binary(1).通过使用字符串操作函数可以到达任何其他函数(binary是一个字符串,只是一个字符串).binary不允许你做类似的事情0x01000 = 0- 包括隐式转换int(在这种情况下),所以通常的规则适用 - 0x0100000000 = 0是真的.
另请注意,无法保证binarySQL Server版本之间的转换是一致的 - 它们并未真正得到管理.