I was running a trace on one of our test servers when someone did this:
and one of the queries I could catch in the trace was:
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]
there is lots of information that can fit in a int if you know –
How does the operator & work?
Best Answer
A single ampersand is the Bitwise AND operator. The numbers on either side represent the value of one or more bit positions:
Hence,
34
is made up of bitwise values of2
and32
.A very simple example showing that the
&
operator will return whatever value(s) is/are present on both sides is:Looking back at the code you posted in the question, you should be able to see how it can be used to determine if one or more bits / flags are "set" within a given value. For example, let's say you want to require that
AnsiPadding
(value = 16),AnsiNulls
(value = 32) andQuotedIdentifier
(value = 256) are set toON
. You would add up those individual values --16 + 32 + 256
-- and then compare the total --304
-- with some "current" value, let's say7000
(values 8 + 16 + 64 + 256 + 512 + 2048 + 4096):The result,
272
, is the combination of16
and256
. So if you want to require those 3 options (additional options will not adversely affect the result), you would use:As you can see, bitwise operations allow you to extract one or more "options" from one or more "options". But, in the code that you posted, they are just looking for individual options since using
&
with an individual bitwise value will return0
if not present or that particular bitwise value if present. And theCAST
to theBIT
datatype will reduce all of those variations to either0
(if the&
yielded a0
) or1
(if the&
yielded anything else).Please note that for the bitwise operators, either side (i.e. expression) can be:
However, counter-intuitively:
That's right: "binary" operations do not work on purely "binary" data ;-). Attempting to do what seems entirely reasonable:
will result in the following error:
In practical terms, this means that bitwise operations are constrained by the upper-limit of the
BIGINT
datatype (which is 8 bytes / 64 bits). Hence:BIGINT
is signed)2 ^ 62
; 62 being the 63rd bit position))(2 ^ 63) - 1
; all 63 bits present / set to "on")Meaning: if you need to handle more than 63 flags / options, then you won't be using the
&
operator ;-).