Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 二进制位转换_Sql Server_Tsql - Fatal编程技术网

Sql server 二进制位转换

Sql server 二进制位转换,sql-server,tsql,Sql Server,Tsql,基于这个问题 有人能给我指一下下面的解释吗 如果我将二进制(4)常量0x8000000转换为int,则取结果值并将其转换为位类型,结果为1 select cast(0x80000000 as int) --> -2147483648 select cast(-2147483648 as bit) --> 1 但是如果我直接将0x8000000强制转换为位类型,结果是0 select cast(0x80000000 as bit) --> 0 我希望在这种情况下也能得到1,我

基于这个问题

有人能给我指一下下面的解释吗

如果我将
二进制(4)
常量
0x8000000
转换为
int
,则取结果值并将其转换为
类型,结果为1

select cast(0x80000000 as int) --> -2147483648
select cast(-2147483648 as bit) --> 1
但是如果我直接将
0x8000000
强制转换为位类型,结果是0

select cast(0x80000000 as bit) --> 0
我希望在这种情况下也能得到1,我想这个表达式可能相当于

select cast(cast(0x80000000 as binary(1)) as bit)
但事实并非如此。相反,似乎二进制常量的最高字节被取出来并转换为位。所以,实际上,它是这样的

select cast(cast(right(0x80000000, 1) as binary(1)) as bit)
我很清楚第一个
binary->int->bit
part。我不清楚的是第二个
binary->bit
部分。我无法在中找到这种行为的解释,其中只有

转换为位会将任何非零值提升为1


是的,一般来说,当从任意长度的二进制或varbinary值转换为固定大小的类型时,转换的是最右边的位或字节:

select
CAST(CAST(0x0102030405060708 as bigint) as varbinary(8)),
CAST(CAST(0x0102030405060708 as int) as varbinary(8)),
CAST(CAST(0x0102030405060708 as smallint) as varbinary(8)),
CAST(CAST(0x0102030405060708 as tinyint) as varbinary(8))
产生:

------------------ ------------------ ------------------ ------------------
0x0102030405060708 0x05060708         0x0708             0x08
实际上,我在文档中找不到明确说明这一点的任何地方,但在这里,基本上是说二进制和其他类型之间的转换不保证遵循任何特定的约定:

如果在同一版本的SQL Server上进行两次转换,则将任何类型的任何值转换为足够大的二进制值,然后再转换回该类型,将始终得到相同的值。值的二进制表示形式可能因SQL Server的版本而异


因此,上面显示的转换是在我的机器上SQL Server 2012上运行的“预期”结果,但其他转换可能会得到不同的结果。

二进制
不是一个数字,而是一个字节字符串。将
二进制
转换为其他类型时,将执行转换。当
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
正如文件所说:

当数据从字符串数据类型(char、varchar、nchar、nvarchar、binary、varbinary、text、ntext或image)转换为长度不等的binary或varbinary数据类型时,SQL Server会填充或截断右侧的数据。当其他数据类型转换为binary或varbinary时,数据将在左侧填充或截断。填充是通过使用十六进制零实现的

这是您可以使用的,因为:

select cast(0x0100 as binary(1)) -- 0x01
因此,如果需要整个值为非零,基本上需要转换为整数数据类型(如果可能)。如果需要最右边的字节,请使用
转换为位
,如果需要最左边的字节,请使用
转换为二进制(1)
。使用字符串操作函数可以访问任何其他字符串(
binary
是字符串,而不是字符串)
binary
不允许您执行类似于
0x01000=0
的操作,这包括到
int
的隐式转换(在本例中),因此通常的规则适用-
0x0100000000=0
是真的


还要注意的是,不能保证SQL server版本之间从
二进制文件的转换是一致的-它们不是真正管理的。

好吧,似乎在
类型文档中寻找答案是错误的,我应该在
二进制文件中进行转换。严格地说是医生。您引用的语句是关于类型->二进制转换的,这里的问题是关于二进制->类型的。在IMO中,假设反向转换具有类似的行为(尽管在实践中得到了证实)具有一定程度的隐含性。尽管如此,由于博士对此还不够明确,我还是给出了这个答案。感谢您指向char/binary和其他类型的不同左/右截断/填充。@i-one实际上,转换是通过契约可逆的,只有当相同的规则双向工作时,契约才起作用。由于定义了类型->二进制,并且定义了类型->二进制->类型,所以只要使用相同的SQL server版本,也会定义二进制->类型。但是,首先在二进制和非字符串类型之间进行任何转换,已经违反了跨版本的考虑。