【问题标题】:How to flip bit fields in T-SQL?如何翻转 T-SQL 中的位域?
【发布时间】:2009-09-09 03:00:43
【问题描述】:

我正在尝试使用更新查询翻转 SQL Server 中的位字段,也就是说,我想将所有 0 变为 1,反之亦然。什么是最优雅的解决方案?

T-SQL 中似乎没有按位 NOT 运算符(除非我遗漏了一些明显的东西),而且我找不到任何其他执行更新的方法。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    您不需要按位进行 - 只需将其与 1 / true 异或即可。

    检查:

    select idColumn, bitFieldY, bitFieldY ^ 1 as Toggled
    from tableX
    

    更新:

    update tableX
    set bitFieldY = bitFieldY ^ 1
    where ...
    

    MSDN T-SQL Exclusive-OR (^)

    【讨论】:

    • 太棒了!谢谢你 - 它就像一个魅力。我显然需要更多地了解如何使用二元运算符
    • 请记住,bitFieldY ^ 1 将返回 int,因此如果您需要它再次成为 bitCASTCONVERT 将返回到 bit
    【解决方案2】:

    为什么不简单的bitfield = 1 - bitfield

    【讨论】:

    • 一种巧妙而优雅的方法,特别是对于一次性查询,可读性并不重要。
    • @Billious 和 GBN 你们都是对的,但我想 Austin 的回复足以理解目标的明确含义。用 1-x 翻转一点会使新手感到困惑,因此不是实现它的正确方法。我也同意做某事的方法不止一种,但如果有推荐的方法,我们应该采用它,这可能比不推荐的方法更快。
    • 对于可以为空的bitfield,一种方法可能是bitfield = 1 - ISNULL(bitfield,0)。请参阅文档中的ISNULL
    • @UweKeim 就个人而言,我不使用 NULLable 位。从来没有真正需要 3 个状态来处理比特
    • 谢谢,@gbn。我有时在有一个遗留表时会这样做,我稍后会在其中添加一个新的位域列。 (如果有更多的知识,这可能会更优雅地解决)。
    【解决方案3】:

    另一种方法是

    DECLARE @thebit bit = 1, @theflipbit bit
    
    SET @theflipbit = ~ @thebit
    
    SELECT @theflipbit
    

    其中“~”表示“NOT”运算符。它很干净,您可以阅读很好的代码。 “否定位”更加简洁,它完全符合“NOT”运算符的设计目的。

    【讨论】:

    • 同样的想法,但将 NULLS 变为 true:UPDATE TABLE_NAME SET BIT_FIELD= IIF(BIT_FIELD IS NULL,1,~ BIT_FIELD)
    【解决方案4】:

    我很确定大多数 SQL 风格都有按位 NOT,所以我检查了一下,确实有 appear to be one in TSQL

    从文档中,它是字符 ~

    【讨论】:

    • SELECT ~MyBitField from MyTable 换句话说,更新 MyTable set MyBitField = ~MyBitField
    【解决方案5】:
    UPDATE tblTest SET MyBitField = CASE WHEN MyBitField = 1 THEN 0 ELSE 1 END
    

    这很乏味,但每个人都会明白它在做什么。

    编辑:

    您可能还需要按照 cmets 中的建议考虑空值。当然取决于你的需求。

    UPDATE tblTest SET 
       MyBitField = CASE 
          WHEN MyBitField = 1 THEN 0 
          WHEN MyBitField = 0 THEN 1
          ELSE NULL -- or 1 or 0 depending on requirements
       END
    

    【讨论】:

    • 这会将 MyBitField 设置为 1,当它以 NULL 开始时。不完全是翻转位。
    • 我认为这是不言而喻的......但我会添加有关处理空值的信息以防万一。
    • 我倾向于同意其他一些人的观点并选择 ~ 或 "^ 1 "。特别是如果这是一次性的事情(看起来更干净)。但是,如果这会持续存在并且可维护性存在问题,那么这个解决方案肯定是最直接的。
    • 在我的例子中,这是一个一次性查询,所以可维护性不是问题,但是,是的,这同样可以很好地工作。我实际上已经编写了一个类似的查询,但无法让 CASE 语句正常工作。我现在意识到这是一个简单的语法错误。哦!
    • 我也喜欢这个。我有时会发现,如果我在代码中遇到一个我不理解的符号,那么很难弄清楚编码器的意图。但这很明显。
    【解决方案6】:

    一个简单的按位非运算符 (~) 在 SQL Server 2014 - 12.0.2269.0 中为我工作

    在 T-SQL 中的更新子句中 -

            Update TableName
            SET    [bitColumnName] = ~[bitColumnName],
                   ....
            WHERE  ....
    

    希望对你有帮助

    参考 - https://docs.microsoft.com/en-us/sql/t-sql/language-elements/bitwise-not-transact-sql

    【讨论】:

      【解决方案7】:

      你试过了吗?

      UPDATE mytable SET somecolumn = 
        CASE WHEN somecolumn = 0 THEN 1 
             WHEN somecolumn IS NULL THEN NULL
             WHEN somecolumn = 1 THEN 0
        END
      

      【讨论】:

        【解决方案8】:

        查询 (vb)

        x = "select x from table"
        

        更新(vb)

        "update table set x=" Not(x*(1))
        

        【讨论】:

        • 即使在 vb 中这也不起作用,问题是针对 t-sql
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-07
        • 1970-01-01
        • 2020-02-25
        • 1970-01-01
        • 2017-05-07
        • 2013-04-20
        • 1970-01-01
        相关资源
        最近更新 更多