【问题标题】:What is the meaning behind this SQL Statement? ISNULL(Status,0) & 128 = 0?这个 SQL 语句背后的含义是什么? ISNULL(状态,0)& 128 = 0?
【发布时间】:2020-03-24 20:59:38
【问题描述】:

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

ISNULL(Status,0) & 128 = 0

它究竟是什么意思或它是如何比较的?我了解isnull 的条件,但单& 运营商的目的是什么,想知道。谁能推荐我?

【问题讨论】:

  • ISNULL& 128= 0 哪一部分你不明白?我不确定在这种情况下条件是什么意思,并且在该子句的ISNULL 之前不应该有任何内容。我也会避免在WHERE 中使用ISNULL

标签: sql sql-server sql-server-2008 sql-server-2008-r2


【解决方案1】:

以下条件:

ISNULL(Status,0) & 128 = 0

评估Status (=128) 的第 8 位是否设置。

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

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

  • 如果StatusNULL,则使用Status 的值或0
  • 按位AND这个值为128
  • 如果按位 AND 返回 0,则返回 true(因此未设置该位)

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

【讨论】:

    【解决方案2】:

    && (Bitwise AND) (Transact-SQL) 并定义为:

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

    ...

    备注

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

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

    在这种情况下,当 Status 的值具有位值 128 (10000000) 的 1 时,条件将为 false。所以像128-255 这样的数字将不符合WHERE 子句的要求,或者像412 (0110011100) 这样的数字,因为表示128 的位的值是1

    顺便说一句,我个人会将以上内容写成:

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

    【讨论】:

      【解决方案3】:

      说明:

      语句ISNULL(Status, 0) & 128 = 0 检查Status 列的8th 位是否等于1ISNULL() 将 NULL 替换为指定的替换值,& (bitwise 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
      

      【讨论】:

        猜你喜欢
        • 2014-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-01
        • 1970-01-01
        • 2015-12-04
        • 2013-08-20
        • 1970-01-01
        相关资源
        最近更新 更多