此 SQL 语句背后的含义是什么?ISNULL(Status,0) & 128 = 0?



我的应用程序中的一些存储过程,使用如下WHERE条件:

ISNULL(Status,0) & 128 = 0

它到底是什么意思或如何比较?我了解isnull条件,但单&操作员的目的是什么,想知道。谁能建议我?

以下条件:

ISNULL(Status,0) & 128 = 0

计算设置第 8 位Status(=128( 的情况。

使用&运算符执行按位AND来计算两个值是否共享相同的位。

在上述情况下,您可以将其分解为:

  • 如果NULL,则使用Status或 0 的值Status
  • 按位将此值AND为 128
  • 如果按位AND返回0,则返回 true(因此未设置位(

顺便说一下,如果设置了Status上的位,这将返回128而不是0

解释:

该语句ISNULL(Status, 0) & 128 = 0检查Status列的8th位是否等于1。ISNULL(( 将 NULL 替换为指定的替换值,&(按位 AND(在两个整数值之间执行按位逻辑 AND 运算。

对此检查的一种解释是,有时将多个位值存储在一列中比为每个值创建多个位列更合适。此方法基于使用POWER函数的附加计算。之后,需要& (BITWISE AND)运算符来获取每个存储的交换机的值。

例:

下一个示例基于问题中的语句,演示如何将 7 个开关的值存储在一列中,然后检查给定开关的状态。

-- Calculation
DECLARE @switch int
SELECT @switch = (
POWER(2 * 0, 1) +  -- switch 1 is off
POWER(2 * 0, 2) +  -- switch 2 is off
POWER(2 * 0, 3) +  -- switch 3 is off
POWER(2 * 0, 4) +  -- switch 4 is off
POWER(2 * 0, 5) +  -- switch 5 is off
POWER(2 * 0, 6) +  -- switch 6 is off
POWER(2 * 1, 7)    -- switch 7 is on
)   
-- Check for switch 7. 128 is equal to POWER(2, 7)
IF ISNULL(@switch, 0) & 128 = 0 PRINT 'OFF' ELSE PRINT 'ON'
-- All checks
SELECT 
CASE WHEN ISNULL(@switch, 0) & POWER(2, 1) /* or 2 */   = 0 THEN 'Switch1 is OFF' ELSE 'Switch1 IS ON' END,
CASE WHEN ISNULL(@switch, 0) & POWER(2, 2) /* or 4 */   = 0 THEN 'Switch2 is OFF' ELSE 'Switch2 IS ON' END,
CASE WHEN ISNULL(@switch, 0) & POWER(2, 3) /* or 8 */   = 0 THEN 'Switch3 is OFF' ELSE 'Switch3 IS ON' END,
CASE WHEN ISNULL(@switch, 0) & POWER(2, 4) /* or 16 */  = 0 THEN 'Switch4 is OFF' ELSE 'Switch4 IS ON' END,
CASE WHEN ISNULL(@switch, 0) & POWER(2, 5) /* or 32 */  = 0 THEN 'Switch5 is OFF' ELSE 'Switch5 IS ON' END,
CASE WHEN ISNULL(@switch, 0) & POWER(2, 6) /* or 64 */  = 0 THEN 'Switch6 is OFF' ELSE 'Switch6 IS ON' END,
CASE WHEN ISNULL(@switch, 0) & POWER(2, 7) /* or 128 */ = 0 THEN 'Switch7 is OFF' ELSE 'Switch7 IS ON' END

&是&(Bitwise AND((Transact-SQL(,定义为:

在两个整数值之间执行按位逻辑 AND 运算。

言论

&位运算符在两个表达式之间执行按位逻辑 AND,为两个表达式获取每个对应的位。当且仅当输入表达式中的两个位(对于正在解析的当前位(的值均为 1 时,结果中的位设置为 1;否则,结果中的位设置为 0。

如果左表达式和右表达式具有不同的整数数据类型(例如,左表达式为 smallint,右表达式为 int(,则较小数据类型的参数将转换为较大数据类型。在这种情况下,smallint表达式被转换为 int。

在这种情况下,当Status的值对位值 128 (10000000( 有一个1时,条件将为假。因此,诸如128-255之类的数字将不符合WHERE子句要求,或者像412(0110011100( 这样的数字,因为表示 128 的位的值为1

附带说明一下,我个人会把上面写成:

WHERE (Status & 128 = 0 OR Status IS NULL)

相关内容

最新更新