Mar*_*lli 6 sql-server t-sql sql-server-2014 operator bitwise-comparison
当有人这样做时,我正在我们的一台测试服务器上运行跟踪:
我可以在跟踪中捕获的查询之一是:
declare @UserOption int
select @UserOption=convert(int, c.value) from sys.configurations c where c.name='user options'
SELECT
CAST(@UserOption & 1 AS bit) AS [DisableDefaultConstraintCheck],
CAST(@UserOption & 2 AS bit) AS [ImplicitTransactions],
CAST(@UserOption & 4 AS bit) AS [CursorCloseOnCommit],
CAST(@UserOption & 8 AS bit) AS [AnsiWarnings],
CAST(@UserOption & 16 AS bit) AS [AnsiPadding],
CAST(@UserOption & 32 AS bit) AS [AnsiNulls],
CAST(@UserOption & 64 AS bit) AS [AbortOnArithmeticErrors],
CAST(@UserOption & 128 AS bit) AS [IgnoreArithmeticErrors],
CAST(@UserOption & 256 AS bit) AS [QuotedIdentifier],
CAST(@UserOption & 512 AS bit) AS [NoCount],
CAST(@UserOption & 1024 AS bit) AS [AnsiNullDefaultOn],
CAST(@UserOption & 2048 AS bit) AS [AnsiNullDefaultOff],
CAST(@UserOption & 4096 AS bit) AS [ConcatenateNullYieldsNull],
CAST(@UserOption & 8192 AS bit) AS [NumericRoundAbort],
CAST(@UserOption & 16384 AS bit) AS [AbortTransactionOnError]
Run Code Online (Sandbox Code Playgroud)
如果您知道,有很多信息可以放入 int 中 -
操作员如何工作?
Sol*_*zky 13
单个与号是按位与运算符。两边的数字代表一个或多个位位置的值:
Actual binary (not BINARY datatype), evaluated from right to left -> 00100010
BIT Position Value (Position ^ 2) "Selected"
0 0 1 0
1 1 2 2
0 2 4 0
0 3 8 0
0 4 16 0
1 5 32 32
0 6 64 0
0 7 128 0
... ... ... ...
0 62 4611686018427387904 0
Run Code Online (Sandbox Code Playgroud)
因此,34
由按位值可达2
和32
。
示出了一个非常简单的示例&
运算符将返回的任何值(多个)/存在于两个侧面是:
SELECT 1 & 1 -- 1
SELECT 1 & 2 -- 0 (because 2 is made up of only 2)
SELECT 1 & 3 -- 1 (because 3 is made up of 1 and 2)
SELECT 2 & 2 -- 2
SELECT 2 & 3 -- 2 (because 3 is made up of 1 and 2)
SELECT 2 & 4 -- 0 (because 4 is made up of only 4)
SELECT 3 & 4 -- 0 (because 3 is made up of 1 and 2, while 4 is made up of only 4)
SELECT 3 & 5 -- 1 (because 3 is made up of 1 and 2, while 5 is made up of 1 and 4)
SELECT 3 & 11 -- 3 (because 3 is made up of 1 and 2, while 11 is made up of 1, 2, and 8)
Run Code Online (Sandbox Code Playgroud)
回顾您在问题中发布的代码,您应该能够看到如何使用它来确定在给定值中是否“设置”了一个或多个位/标志。例如,假设您希望将AnsiPadding
(value = 16)、AnsiNulls
(value = 32) 和QuotedIdentifier
(value = 256) 设置为ON
。您可以将这些单个值相加 -- 16 + 32 + 256
-- 然后将总数 -- 304
-- 与一些“当前”值进行比较,例如7000
(值 8 + 16 + 64 + 256 + 512 + 2048 + 4096):
SELECT 304 & 7000; -- 272
Run Code Online (Sandbox Code Playgroud)
其结果,272
是的组合16
和256
。因此,如果您想要这 3 个选项(附加选项不会对结果产生不利影响),您可以使用:
IF (@options & 304 = 304)
BEGIN
...
END;
Run Code Online (Sandbox Code Playgroud)
如您所见,按位运算允许您从一个或多个“选项”中提取一个或多个“选项”。但是,在您发布的代码中,他们只是在寻找单个选项,因为使用&
单个按位值将返回(0
如果不存在)或该特定的按位值(如果存在)。并且CAST
toBIT
数据类型会将所有这些变化减少到0
(如果&
产生了 a 0
)或1
(如果&
产生了其他任何东西)。
请注意,对于按位运算符,任一侧(即表达式)可以是:
整数数据类型类别、位、二进制或varbinary数据类型的任何数据类型。
然而,与直觉相反:
在按位运算中,只有一个表达式可以是binary或varbinary数据类型。
没错:“二进制”操作不适用于纯粹的“二进制”数据;-)。试图做看起来完全合理的事情:
SELECT 0x03 & 0x0B;
Run Code Online (Sandbox Code Playgroud)
将导致以下错误:
消息 402,级别 16,状态 1,第 28 行
“&”运算符中的数据类型 varbinary 和 varbinary 不兼容。
实际上,这意味着按位运算受BIGINT
数据类型上限(8 字节/64 位)的限制。因此:
BIGINT
有符号)2 ^ 62
62 是第 63 位位置))(2 ^ 63) - 1
,所有 63 位都存在/设置为“on”)意思是:如果您需要处理超过 63 个标志/选项,那么您将不会使用&
运算符 ;-)。
归档时间: |
|
查看次数: |
19919 次 |
最近记录: |