Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.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/8/api/5.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_Sql Server_Tsql - Fatal编程技术网

在sql server中,如何在两种二进制类型之间执行按位异或?

在sql server中,如何在两种二进制类型之间执行按位异或?,sql,sql-server,tsql,Sql,Sql Server,Tsql,根据此链接: 我们可以在二进制和int、smallint、tinyint之间进行位运算,反之亦然 但是如何在sql server中在两个二进制类型之间生成位异或? 或者,如果这不可能,我如何将二进制/varbinary拆分为单个字节 我之所以要求这样做,是因为我需要对两个大于max int值的数字进行异或运算。 谢谢。请点击: 注意 只有一个表达式可以是binary或varbinary数据类型 在按位操作中 我使用bigint来存储这两个值。这样你会有更大的射程。如果值大于bigint,则可能需

根据此链接: 我们可以在二进制和int、smallint、tinyint之间进行位运算,反之亦然

但是如何在sql server中在两个二进制类型之间生成位异或? 或者,如果这不可能,我如何将二进制/varbinary拆分为单个字节

我之所以要求这样做,是因为我需要对两个大于max int值的数字进行异或运算。 谢谢。

请点击:

注意

只有一个表达式可以是binary或varbinary数据类型 在按位操作中


我使用bigint来存储这两个值。这样你会有更大的射程。如果值大于bigint,则可能需要将值拆分为两个bigint,并使用和/或运算符组合

Martin在问题中的评论让我想到了如何拆分二进制文件,以便对值进行异或运算。 最初我想在sql中对两个GUID进行异或运算。下面是我附带的代码:

declare @guid1 uniqueidentifier
declare @guid2 uniqueidentifier
declare @guid3_hi binary(8)
declare @guid3_lo binary(8)
declare @guid3_temp varchar(32)
declare @guid3_char varchar(36)
declare @guid3 uniqueidentifier

set @guid1 = '96B4316D-1EA7-4CA3-8D50-FEE8047C1329'
set @guid2 = 'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF'

set @guid3_hi = CAST(SUBSTRING(CAST(@guid1 as binary(16)),1,8) as bigint) ^ CAST(SUBSTRING(CAST(@guid2 as binary(16)),1,8) as bigint)
set @guid3_lo = CAST(SUBSTRING(CAST(@guid1 as binary(16)),9,8) as bigint) ^ CAST(SUBSTRING(CAST(@guid2 as binary(16)),9,8) as bigint)

set @guid3_temp = SUBSTRING(dbo.sp_hexadecimal(@guid3_hi), 3, 16) + SUBSTRING(dbo.sp_hexadecimal(@guid3_lo), 3, 16)
select @guid3_temp

set @guid3_char = SUBSTRING(@guid3_temp, 1, 8) + '-' + SUBSTRING(@guid3_temp, 9, 4) + '-' + SUBSTRING(@guid3_temp, 13, 4) + '-' + SUBSTRING(@guid3_temp, 17, 4) + '-' + SUBSTRING(@guid3_temp, 21, 12)
select @guid3_char

set @guid3 = convert(uniqueidentifier, @guid3_char)
select @guid3

--result 92CE4B69-58E1-5CB3-72AF-0117FB83ECD6
将二进制转换为十六进制字符串的函数来自:

我知道,在SQL2008中,我们可以使用convert函数来实现这一点,正如这篇文章所解释的:,但在我的例子中,这不是一个选项

不过,如果有人对如何在二进制数据类型上使用SQL逐位操作有更好的了解,那就太好了

编辑:

感谢cyberkiwi提供了正确的算法并指出了我代码中的错误。
这段代码可以用于二进制的异或,但不适用于guid,因为guid的前8个字节和后8个字节的字节顺序不同。请查看维基百科对此的解释:。请注意,如果要将XOR ed结果用作实际GUID,则应考虑版本位。

代码块中的所有注释

-- variables
declare @vb1 binary(16), @vb2 binary(16), @lo binary(8), @hi binary(8)

-- 2 guids to compare
declare @guid1 uniqueidentifier set @guid1 = '96B4316D-1EA7-4CA3-8D50-FEE8047C1329'
declare @guid2 uniqueidentifier set @guid2 = 'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF'

-- split every 8 bytes into a binary(8), which is a bigint, the largest size usable with XOR
select @vb1 = @guid1, @vb2 = @guid2

-- xor the high and low parts separately
select @hi = convert(binary(8), substring(@vb1,1,8)) ^ convert(bigint, substring(@vb2,1,8))
select @lo = convert(binary(8), substring(@vb1,9,8)) ^ convert(bigint, substring(@vb2,9,8))

-- the final result, concatenating the bytes using char(8) - binary -> uniqueidentifier
select 'A', @guid1 union all
select 'B', @guid2 union all
select 'A XOR B = ', convert(uniqueidentifier, convert(binary(16),convert(char(8),@hi) + convert(char(8),@lo)))

已尝试但不起作用:“布尔异或运算符中的数据类型二进制和二进制不兼容。”
a^b
是否等同于
(a | b)&!(a&b)
?或者我在这里有一个derp时刻?是的,但是sql server的按位限制适用于所有操作,而不仅仅是XOR。查看问题中的链接。您是否已经看到(包括Celko在这个想法上的一些滥用和几个UDF建议)?它将增加多少位/您知道为什么会这样吗?我猜返回变量的大小是不确定的……但它不能大于二进制中传递的最大值。这个结果不对吗?每个字节的补码(XOR)在第一个位置加起来应该是F.9+9>F。比较最后4个字符
1329+ECD6=FFFF
@cyberkiwi当然结果是错误的,谢谢你指出这一点。我只是忽略了结果,因为只查看了奇怪地正确的最后8个字节。问题是将uniqueidentifier强制转换为二进制,但该二进制无法正确转换前8个字节。了解发生这种情况的原因以及如何将uniqueidentifier正确转换为二进制是很有意思的。可能已经过时,但在最后一行中,您可以将其简化为选择“A XOR B=”,convert(uniqueidentifier,@hi+@lo)